ladishd: generic object refcounting for port and client objects

This commit is contained in:
Nedko Arnaudov 2012-09-15 07:00:48 +03:00
parent 08cec66e66
commit fe2d8d3bcd
14 changed files with 193 additions and 139 deletions

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains the implementation of the client objects
@ -29,6 +29,7 @@
struct ladish_client
{
ladish_object obj;
uuid_t uuid; /* The UUID of the client */
uuid_t uuid_interlink; /* The UUID of the linked client (vgraph <-> jack graph) */
uuid_t uuid_app; /* The UUID of the app that owns this client */
@ -40,6 +41,8 @@ struct ladish_client
void * vgraph; /* virtual graph */
};
static void ladish_client_destroy(ladish_client_handle client_handle);
bool
ladish_client_create(
const uuid_t uuid_ptr,
@ -73,6 +76,8 @@ ladish_client_create(
uuid_clear(client_ptr->uuid_interlink);
uuid_clear(client_ptr->uuid_app);
ladish_object_init(&client_ptr->obj, 1, (ladish_object_destructor)ladish_client_destroy);
client_ptr->jack_id = 0;
client_ptr->jack_name = NULL;
client_ptr->pid = 0;
@ -102,9 +107,7 @@ ladish_client_create_copy(
return ladish_client_create(client_ptr->uuid, client_handle_ptr);
}
void
ladish_client_destroy(
ladish_client_handle client_handle)
static void ladish_client_destroy(ladish_client_handle client_handle)
{
log_info("client %p destroy", client_ptr);

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains the interface of the client objects
@ -41,10 +41,6 @@ ladish_client_create_copy(
ladish_client_handle client_handle,
ladish_client_handle * client_handle_ptr);
void
ladish_client_destroy(
ladish_client_handle client_handle);
ladish_dict_handle ladish_client_get_dict(ladish_client_handle client_handle);
void ladish_client_get_uuid(ladish_client_handle client_handle, uuid_t uuid);

View File

@ -233,7 +233,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
{
log_error("ladish_graph_add_client() failed to add client '%s' to JACK graph", name_dup);
context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL;
goto free;
}
@ -282,7 +282,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
{
log_error("ladish_graph_add_client() failed to add client '%s' to studio graph", name_dup);
context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL;
goto free;
}
@ -834,6 +834,7 @@ static void callback_elend(void * data, const char * UNUSED(el))
{
//log_info("</client>");
ASSERT(context_ptr->client != NULL);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL;
}
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_PORT)

View File

@ -234,19 +234,19 @@ create_room_template(
if (!ladish_graph_add_client(graph, capture, "Capture", false))
{
log_error("ladish_graph_add_client() failed to add capture client to room template \"%s\".", name);
goto fail_destroy;
goto fail_unref_capture;
}
if (!ladish_client_create(ladish_wkclient_playback, &playback))
{
log_error("ladish_client_create() failed to create playback client to room template \"%s\".", name);
goto fail_destroy;
goto fail_unref_capture;
}
if (!ladish_graph_add_client(graph, playback, "Playback", false))
{
log_error("ladish_graph_add_client() failed to add playback client to room template \"%s\".", name);
goto fail_destroy;
goto fail_unref_capture;
}
room_descriptor_ptr->name = ladish_room_get_name(room);
@ -257,6 +257,8 @@ create_room_template(
return true;
fail_unref_capture:
ladish_del_ref(capture);
fail_destroy:
ladish_room_destroy(room); /* this will destroy the graph clients as well */
fail:

View File

@ -1239,7 +1239,7 @@ ladish_graph_remove_port_internal(
{
ladish_graph_remove_port_connections(graph_ptr, port_ptr);
ladish_port_del_ref(port_ptr->port);
ladish_del_ref(port_ptr->port);
list_del(&port_ptr->siblings_client);
list_del(&port_ptr->siblings_graph);
@ -1260,7 +1260,6 @@ void
ladish_graph_remove_client_internal(
struct ladish_graph * graph_ptr,
struct ladish_graph_client * client_ptr,
bool destroy_client,
ladish_graph_simple_port_callback port_callback)
{
struct ladish_graph_port * port_ptr;
@ -1285,10 +1284,7 @@ ladish_graph_remove_client_internal(
free(client_ptr->name);
if (destroy_client)
{
ladish_client_destroy(client_ptr->client);
}
ladish_del_ref(client_ptr->client);
free(client_ptr);
}
@ -1368,7 +1364,7 @@ void ladish_graph_clear(ladish_graph_handle graph_handle, ladish_graph_simple_po
while (!list_empty(&graph_ptr->clients))
{
client_ptr = list_entry(graph_ptr->clients.next, struct ladish_graph_client, siblings);
ladish_graph_remove_client_internal(graph_ptr, client_ptr, true, port_callback);
ladish_graph_remove_client_internal(graph_ptr, client_ptr, port_callback);
}
}
@ -1525,6 +1521,7 @@ bool ladish_graph_add_client(ladish_graph_handle graph_handle, ladish_client_han
}
client_ptr->id = graph_ptr->next_client_id++;
ladish_add_ref(client_handle);
client_ptr->client = client_handle;
client_ptr->hidden = hidden;
graph_ptr->graph_version++;
@ -1553,7 +1550,7 @@ ladish_graph_remove_client(
client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
if (client_ptr != NULL)
{
ladish_graph_remove_client_internal(graph_ptr, client_ptr, false, NULL);
ladish_graph_remove_client_internal(graph_ptr, client_ptr, NULL);
}
else
{
@ -1625,7 +1622,7 @@ ladish_graph_add_port(
port_ptr->id = graph_ptr->next_port_id++;
port_ptr->port = port_handle;
ladish_port_add_ref(port_ptr->port);
ladish_add_ref(port_ptr->port);
port_ptr->hidden = true;
port_ptr->link = ladish_port_is_link(port_handle);
@ -1819,6 +1816,7 @@ ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_
if (strcmp(client_ptr->name, name) == 0 &&
(!appless || !ladish_client_has_app(client_ptr->client))) /* if appless is true, then an appless client is being searched */
{
ladish_add_ref(client_ptr->client);
return client_ptr->client;
}
}
@ -1840,6 +1838,7 @@ ladish_client_handle ladish_graph_find_client_by_app(ladish_graph_handle graph_h
if (uuid_compare(current_uuid, app_uuid) == 0)
{
ladish_add_ref(client_ptr->client);
return client_ptr->client;
}
}
@ -1896,6 +1895,7 @@ ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_
ladish_client_get_uuid(client_ptr->client, current_uuid);
if (uuid_compare(current_uuid, uuid) == 0)
{
ladish_add_ref(client_ptr->client);
return client_ptr->client;
}
}
@ -1926,6 +1926,7 @@ ladish_client_handle ladish_graph_get_port_client(ladish_graph_handle graph_hand
return NULL;
}
ladish_add_ref(port_ptr->client_ptr->client);
return port_ptr->client_ptr->client;
}
@ -1944,6 +1945,7 @@ ladish_client_handle ladish_graph_find_client_by_id(ladish_graph_handle graph_ha
client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
if (client_ptr->id == client_id)
{
ladish_add_ref(client_ptr->client);
return client_ptr->client;
}
}
@ -1974,6 +1976,7 @@ ladish_client_handle ladish_graph_find_client_by_jack_id(ladish_graph_handle gra
client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
if (ladish_client_get_jack_id(client_ptr->client) == client_id)
{
ladish_add_ref(client_ptr->client);
return client_ptr->client;
}
}
@ -2050,10 +2053,11 @@ bool ladish_graph_client_has_visible_ports(ladish_graph_handle graph_handle, lad
return false;
}
ladish_client_handle
bool
ladish_graph_remove_port(
ladish_graph_handle graph_handle,
ladish_port_handle port)
ladish_port_handle port,
ladish_client_handle * client_ptr)
{
struct ladish_graph_port * port_ptr;
ladish_client_handle client;
@ -2061,15 +2065,23 @@ ladish_graph_remove_port(
port_ptr = ladish_graph_find_port(graph_ptr, port);
if (port_ptr == NULL)
{
return NULL;
return false;
}
client = port_ptr->client_ptr->client;
ASSERT(client != NULL);
ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr);
return client;
if (client_ptr != NULL)
{
ladish_add_ref(client);
*client_ptr = client;
}
return true;
}
ladish_client_handle
void
ladish_graph_remove_port_by_jack_id(
ladish_graph_handle graph_handle,
uint64_t jack_port_id,
@ -2077,17 +2089,14 @@ ladish_graph_remove_port_by_jack_id(
bool studio)
{
struct ladish_graph_port * port_ptr;
ladish_client_handle client;
port_ptr = ladish_graph_find_port_by_jack_id_internal(graph_ptr, jack_port_id, room, studio);
if (port_ptr == NULL)
{
return NULL;
return;
}
client = port_ptr->client_ptr->client;
ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr);
return client;
}
void
@ -2899,7 +2908,7 @@ void ladish_graph_remove_hidden_objects(ladish_graph_handle graph_handle)
client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
if (client_ptr->hidden)
{
ladish_graph_remove_client_internal(graph_ptr, client_ptr, true, NULL);
ladish_graph_remove_client_internal(graph_ptr, client_ptr, NULL);
}
}
}
@ -2991,7 +3000,7 @@ ladish_graph_copy_client_begin_callback(
if (!ladish_graph_add_client(context, copy, client_name, false))
{
ladish_client_destroy(copy);
ladish_del_ref(copy);
return false;
}
@ -3000,6 +3009,20 @@ ladish_graph_copy_client_begin_callback(
return true;
}
static
bool
ladish_graph_copy_client_end_callback(
void * UNUSED(context),
ladish_graph_handle UNUSED(graph_handle),
bool UNUSED(hidden),
ladish_client_handle UNUSED(client_handle),
const char * UNUSED(client_name),
void * client_iteration_context_ptr)
{
ladish_del_ref(client_iteration_context_ptr);
return true;
}
static
bool
ladish_graph_copy_port_callback(
@ -3039,7 +3062,7 @@ bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest)
dest,
ladish_graph_copy_client_begin_callback,
ladish_graph_copy_port_callback,
NULL);
ladish_graph_copy_client_end_callback);
}
CDBUS_METHOD_ARGS_BEGIN(GetAllPorts, "Get all ports")

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains interface to the D-Bus patchbay interface helpers
@ -90,12 +90,13 @@ ladish_graph_add_port(
uint32_t flags,
bool hidden);
ladish_client_handle
bool
ladish_graph_remove_port(
ladish_graph_handle graph_handle,
ladish_port_handle port_handle);
ladish_port_handle port_handle,
ladish_client_handle * client_ptr);
ladish_client_handle
void
ladish_graph_remove_port_by_jack_id(
ladish_graph_handle graph_handle,
uint64_t jack_port_id,

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009,2010,2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains interface to the D-Bus graph dict interface helpers
@ -50,6 +50,7 @@ bool find_dict(struct cdbus_method_call * call_ptr, uint32_t object_type, uint64
return false;
}
*dict_handle_ptr = ladish_client_get_dict(client);
ladish_del_ref(client);
return true;
case GRAPH_DICT_OBJECT_TYPE_PORT:
port = ladish_graph_find_port_by_id(graph_handle, object_id);

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* The D-Bus patchbay manager
@ -126,6 +126,8 @@ static void ladish_graph_manager_dbus_rename_client(struct cdbus_method_call * c
{
cdbus_method_return_new_void(call_ptr);
}
ladish_del_ref(client);
}
static void ladish_graph_manager_dbus_rename_port(struct cdbus_method_call * call_ptr)
@ -201,6 +203,7 @@ static void ladish_graph_manager_dbus_move_port(struct cdbus_method_call * call_
}
ladish_graph_move_port(graph, port, client);
ladish_del_ref(client);
cdbus_method_return_new_void(call_ptr);
}
@ -233,11 +236,12 @@ static void ladish_graph_manager_dbus_new_client(struct cdbus_method_call * call
if (!ladish_graph_add_client(graph, client, name, false))
{
cdbus_error(call_ptr, DBUS_ERROR_FAILED, "ladish_graph_add_client() failed to add client '%s' to virtual graph", name);
ladish_client_destroy(client);
ladish_del_ref(client);
return;
}
client_id = ladish_graph_get_client_id(graph, client);
ladish_del_ref(client);
cdbus_method_return_new_single(call_ptr, DBUS_TYPE_UINT64, &client_id);
}
@ -270,10 +274,12 @@ static void ladish_graph_manager_dbus_remove_client(struct cdbus_method_call * c
if (ladish_graph_client_has_visible_ports(graph, client))
{
cdbus_error(call_ptr, DBUS_ERROR_INVALID_ARGS, "Cannot remove non-empty client");
ladish_del_ref(client);
return;
}
ladish_graph_remove_client(graph, client);
ladish_del_ref(client);
cdbus_method_return_new_void(call_ptr);
}

View File

@ -392,6 +392,7 @@ interlink_client(
ladish_client_set_app(jclient, app_uuid);
ladish_client_set_vgraph(jclient, ctx_ptr->vgraph);
ladish_del_ref(vclient);
return true;
}

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains the implementation of the port objects
@ -29,7 +29,7 @@
/* JACK port */
struct ladish_port
{
int refcount;
ladish_object obj;
uuid_t uuid; /* The UUID of the port */
uuid_t app_uuid; /* The UUID of the app that owns this client */
bool link; /* Whether the port is studio-room link port */
@ -76,10 +76,11 @@ ladish_port_create(
uuid_clear(port_ptr->app_uuid);
ladish_object_init(&port_ptr->obj, 0, (ladish_object_destructor)ladish_port_destroy);
port_ptr->jack_id = 0;
port_ptr->jack_id_room = 0;
port_ptr->link = link;
port_ptr->refcount = 0;
port_ptr->vgraph = NULL;
@ -98,7 +99,7 @@ bool ladish_port_create_copy(ladish_port_handle port_handle, ladish_port_handle
void ladish_port_destroy(ladish_port_handle port_handle)
{
log_info("port %p destroy", port_ptr);
ASSERT(port_ptr->refcount == 0);
ASSERT(port_ptr->obj.refcount == 0);
ladish_dict_destroy(port_ptr->dict);
free(port_ptr);
}
@ -143,22 +144,6 @@ uint64_t ladish_port_get_jack_id_room(ladish_port_handle port_handle)
}
}
void ladish_port_add_ref(ladish_port_handle port_handle)
{
port_ptr->refcount++;
}
void ladish_port_del_ref(ladish_port_handle port_handle)
{
ASSERT(port_ptr->refcount > 0);
port_ptr->refcount--;
if (port_ptr->refcount == 0)
{
ladish_port_destroy(port_handle);
}
}
bool ladish_port_is_link(ladish_port_handle port_handle)
{
return port_ptr->link;

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* This file contains the interface of the port objects
@ -42,9 +42,6 @@ uint64_t ladish_port_get_jack_id(ladish_port_handle port_handle);
void ladish_port_set_jack_id_room(ladish_port_handle port_handle, uint64_t jack_id);
uint64_t ladish_port_get_jack_id_room(ladish_port_handle port_handle);
void ladish_port_add_ref(ladish_port_handle port_handle);
void ladish_port_del_ref(ladish_port_handle port_handle);
bool ladish_port_is_link(ladish_port_handle port_handle);
void ladish_port_set_vgraph(ladish_port_handle port_handle, void * vgraph);

View File

@ -245,8 +245,7 @@ static void remove_port_callback(ladish_port_handle port)
jack_graph = ladish_studio_get_jack_graph();
jack_client = ladish_graph_remove_port(jack_graph, port);
if (jack_client == NULL)
if (!ladish_graph_remove_port(jack_graph, port, &jack_client))
{ /* room app port not found in jack graph */
/* this can happen if the port is hidden in the vgraph */
return;
@ -256,6 +255,8 @@ static void remove_port_callback(ladish_port_handle port)
{
ladish_graph_remove_client(jack_graph, jack_client);
}
ladish_del_ref(jack_client);
}
bool
@ -342,7 +343,7 @@ ladish_room_create(
if (!ladish_graph_add_client(owner, room_ptr->client, room_ptr->name, true))
{
log_error("ladish_graph_add_client() failed to add room client to owner graph.");
goto destroy_client;
goto unref_client;
}
if (!ladish_room_iterate_link_ports((ladish_room_handle)room_ptr, room_ptr, create_shadow_port))
@ -351,6 +352,8 @@ ladish_room_create(
goto remove_client;
}
ladish_del_ref(room_ptr->client);
ladish_studio_room_appeared((ladish_room_handle)room_ptr);
*room_handle_ptr = (ladish_room_handle)room_ptr;
@ -358,8 +361,8 @@ ladish_room_create(
remove_client:
ladish_graph_remove_client(owner, room_ptr->client);
destroy_client:
ladish_client_destroy(room_ptr->client);
unref_client:
ladish_del_ref(room_ptr->client);
unregister_dbus_object:
cdbus_object_path_unregister(cdbus_g_dbus_connection, room_ptr->dbus_object);
destroy_dbus_object:
@ -401,7 +404,7 @@ void ladish_room_destroy(ladish_room_handle room_handle)
ladish_app_supervisor_destroy(room_ptr->app_supervisor);
ladish_graph_remove_client(room_ptr->owner, room_ptr->client);
ladish_client_destroy(room_ptr->client);
ladish_del_ref(room_ptr->client);
ladish_studio_room_disappeared((ladish_room_handle)room_ptr);
ladish_studio_release_room_index(room_ptr->index);
@ -742,9 +745,9 @@ ladish_room_add_port(
ladish_port_handle port;
bool playback;
ladish_client_handle client;
ladish_client_handle client2;
const char * client_name;
uuid_t client_uuid;
bool new_client;
playback = port_is_input(flags);
@ -760,8 +763,7 @@ ladish_room_add_port(
/* if client is not found, create it and add it to graph */
client = ladish_graph_find_client_by_uuid(room_ptr->graph, client_uuid);
new_client = client == NULL;
if (new_client)
if (client == NULL)
{
if (!ladish_client_create(client_uuid, &client))
{
@ -772,14 +774,14 @@ ladish_room_add_port(
if (!ladish_graph_add_client(room_ptr->graph, client, client_name, true))
{
log_error("ladish_graph_add_client() failed to add %s room client to room graph.", playback ? "playback" : "capture");
goto fail_destroy_client;
goto fail_unref_client;
}
}
if (!ladish_graph_add_port(room_ptr->graph, client, port, name, type, flags, true))
{
log_error("ladish_graph_add_port() failed to add %s room port \"%s\" to room graph.", playback ? "playback" : "capture", name);
goto fail_destroy_client;
goto fail_unref_client;
}
if (!create_shadow_port(room_ptr, port, name, type, flags))
@ -788,19 +790,21 @@ ladish_room_add_port(
goto fail_remove_port;
}
ladish_del_ref(client);
return port;
fail_remove_port:
ASSERT(client != NULL);
if (ladish_graph_remove_port(room_ptr->graph, port) != client)
if (!ladish_graph_remove_port(room_ptr->graph, port, &client2))
{
ASSERT_NO_PASS;
}
fail_destroy_client:
if (new_client)
if (client2 != client)
{
ladish_client_destroy(client);
ASSERT_NO_PASS;
}
fail_unref_client:
ladish_del_ref(client);
fail_destroy_port:
ladish_port_destroy(port);
fail:

View File

@ -234,7 +234,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
{
log_error("ladish_graph_add_client() failed to add client '%s' to JACK graph", name_dup);
context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL;
}
@ -280,7 +280,7 @@ static void callback_elstart(void * data, const char * el, const char ** attr)
{
log_error("ladish_graph_add_client() failed to add client '%s' to room graph", name_dup);
context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL;
}
@ -711,6 +711,7 @@ static void callback_elend(void * data, const char * UNUSED(el))
{
//log_info("</client>");
ASSERT(context_ptr->client != NULL);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL;
}
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_PORT)

View File

@ -354,7 +354,7 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name)
if (ladish_client_get_jack_id(client) != 0)
{
log_error("Ignoring client with duplicate name '%s' ('%s')", name, jack_name);
goto exit;
goto unref_client;
}
ladish_client_set_jack_name(client, jack_name);
@ -377,8 +377,7 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name)
if (!ladish_graph_add_client(virtualizer_ptr->jack_graph, client, name, false))
{
log_error("ladish_graph_add_client() failed to add client %"PRIu64" (%s) to JACK graph", id, name);
ladish_client_destroy(client);
goto exit;
goto unref_client;
}
done:
@ -409,6 +408,8 @@ done:
ladish_client_set_vgraph(client, g_studio.studio_graph);
}
unref_client:
ladish_del_ref(client);
exit:
return;
}
@ -497,10 +498,11 @@ static void client_disappeared(void * context, uint64_t id)
else
{
ladish_graph_remove_client(virtualizer_ptr->jack_graph, client);
ladish_client_destroy(client);
/* no need to clear vclient interlink because it either does not exist (vgraph is NULL) or
* it will be destroyed before it is accessed (persist flag is cleared on room deletion) */
}
ladish_del_ref(client);
}
static
@ -569,7 +571,7 @@ port_appeared(
if (vgraph == NULL)
{
log_error("Cannot find vgraph for appeared jmcore port '%s'", real_jack_port_name);
goto exit;
goto unref_jack_client;
}
/* jmcore port appeared */
@ -579,7 +581,7 @@ port_appeared(
if (!ladish_graph_add_port(virtualizer_ptr->jack_graph, jack_client, port, real_jack_port_name, type, flags, false))
{
log_error("ladish_graph_add_port() failed.");
goto exit;
goto unref_jack_client;
}
if (vgraph == g_studio.studio_graph)
@ -596,11 +598,12 @@ port_appeared(
{
log_error("link port client not found in vgraph %s", ladish_graph_get_description(vgraph));
ASSERT_NO_PASS;
goto exit;
goto unref_jack_client;
}
ladish_graph_show_port(vgraph, port);
goto exit;
ladish_del_ref(vclient);
goto unref_jack_client;
}
else
{
@ -620,7 +623,7 @@ port_appeared(
if (alsa_client_name == NULL)
{
log_error("catdup failed to duplicate a2j jack client name after map failure");
goto exit;
goto unref_jack_client;
}
alsa_port_name = strdup(real_jack_port_name);
@ -628,7 +631,7 @@ port_appeared(
{
log_error("catdup failed to duplicate a2j jack port name after map failure");
free(alsa_client_name);
goto exit;
goto unref_jack_client;
}
vclient_name = alsa_client_name;
@ -723,6 +726,7 @@ port_appeared(
ladish_client_set_jack_id(vclient, client_id);
ladish_graph_adjust_port(vgraph, port, type, flags);
ladish_graph_show_port(vgraph, port);
ladish_del_ref(vclient);
goto free_alsa_names;
}
@ -775,8 +779,7 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, vclient_name, false))
{
log_error("ladish_graph_add_client() failed.");
ladish_client_destroy(vclient);
goto free_alsa_names;
goto unref_vclient;
}
}
}
@ -799,8 +802,7 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, "Hardware Capture", false))
{
log_error("ladish_graph_add_client() failed.");
ladish_client_destroy(vclient);
goto free_alsa_names;
goto unref_vclient;
}
}
}
@ -817,8 +819,8 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, "Hardware Playback", false))
{
ladish_client_destroy(vclient);
goto free_alsa_names;
log_error("ladish_graph_add_client() failed.");
goto unref_vclient;
}
}
}
@ -868,8 +870,7 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, vclient_name, false))
{
log_error("ladish_graph_add_client() failed to add client '%s' to virtual graph", jack_client_name);
ladish_client_destroy(vclient);
goto free_alsa_names;
goto unref_vclient;
}
}
else
@ -896,14 +897,17 @@ port_appeared(
if (!ladish_graph_add_port(vgraph, vclient, port, vport_name, type, flags, false))
{
log_error("ladish_graph_add_port() failed.");
goto free_alsa_names;
}
unref_vclient:
ladish_del_ref(vclient);
free_alsa_names:
free(a2j_fake_jack_port_name);
free(alsa_client_name);
free(alsa_port_name);
unref_jack_client:
ladish_del_ref(jack_client);
exit:
return;
}
@ -951,6 +955,7 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i
if (port == NULL)
{
log_error("Unknown JACK port with id %"PRIu64" disappeared", port_id);
ladish_del_ref(jclient);
return;
}
@ -964,6 +969,7 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i
{
log_error("Cannot find vgraph for disappeared jmcore port");
ASSERT_NO_PASS;
ladish_del_ref(jclient);
return;
}
@ -992,28 +998,31 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i
{
ladish_graph_hide_client(vgraph, vclient);
}
ladish_del_ref(vclient);
}
}
else
{
if (!jmcore)
{
ladish_graph_remove_port(virtualizer_ptr->jack_graph, port);
ladish_graph_remove_port(virtualizer_ptr->jack_graph, port, NULL);
}
if (vgraph != NULL)
{
vclient = ladish_graph_remove_port(vgraph, port);
if (vclient != NULL)
if (ladish_graph_remove_port(vgraph, port, &vclient))
{
if (ladish_graph_client_is_empty(vgraph, vclient))
{
ladish_graph_remove_client(vgraph, vclient);
ladish_client_clear_interlink(jclient);
}
ladish_del_ref(vclient);
}
}
}
ladish_del_ref(jclient);
}
static
@ -1254,6 +1263,7 @@ ladish_virtualizer_get_our_clients_count(
static bool app_has_a2j_ports(ladish_graph_handle jack_graph, const uuid_t app_uuid)
{
ladish_client_handle a2jclient;
bool ret;
a2jclient = ladish_graph_find_client_by_uuid(jack_graph, g_a2j_uuid);
if (a2jclient == NULL)
@ -1261,7 +1271,9 @@ static bool app_has_a2j_ports(ladish_graph_handle jack_graph, const uuid_t app_u
return false;
}
return ladish_graph_client_has_visible_app_port(jack_graph, a2jclient, app_uuid);
ret = ladish_graph_client_has_visible_app_port(jack_graph, a2jclient, app_uuid);
ladish_del_ref(a2jclient);
return ret;
}
bool
@ -1270,10 +1282,9 @@ ladish_virtualizer_is_hidden_app(
const uuid_t app_uuid,
const char * app_name)
{
ladish_client_handle jclient;
ladish_client_handle client;
ladish_graph_handle vgraph;
uuid_t vclient_uuid;
ladish_client_handle vclient;
//ladish_graph_dump(g_studio.jack_graph);
@ -1283,33 +1294,35 @@ ladish_virtualizer_is_hidden_app(
return false;
}
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (jclient == NULL)
client = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (client == NULL)
{
log_info("App without JACK client is treated as hidden one");
return true;
}
ASSERT(!ladish_virtualizer_is_a2j_client(jclient)); /* a2j client has no app associated */
ASSERT(!ladish_virtualizer_is_a2j_client(client)); /* a2j client has no app associated */
vgraph = ladish_client_get_vgraph(jclient);
vgraph = ladish_client_get_vgraph(client);
if (vgraph == NULL)
{
ASSERT_NO_PASS;
ladish_del_ref(client);
return true;
}
//ladish_graph_dump(vgraph);
if (!ladish_graph_client_looks_empty(jack_graph, jclient) ||
!ladish_graph_client_is_hidden(jack_graph, jclient))
if (!ladish_graph_client_looks_empty(jack_graph, client) ||
!ladish_graph_client_is_hidden(jack_graph, client))
{
ladish_del_ref(client);
return false;
}
if (!ladish_client_get_interlink(jclient, vclient_uuid))
if (!ladish_client_get_interlink(client, vclient_uuid))
{
if (ladish_graph_client_is_empty(jack_graph, jclient))
if (ladish_graph_client_is_empty(jack_graph, client))
{
log_info("jack client of app '%s' has no interlinked vgraph client and no ports", app_name);
}
@ -1318,22 +1331,26 @@ ladish_virtualizer_is_hidden_app(
log_error("jack client of app '%s' has no interlinked vgraph client", app_name);
ASSERT_NO_PASS;
}
ladish_del_ref(client);
return true;
}
vclient = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid);
if (vclient == NULL)
ladish_del_ref(client);
client = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid);
if (client == NULL)
{
ASSERT_NO_PASS;
return true;
}
if (!ladish_graph_client_looks_empty(vgraph, vclient))
if (!ladish_graph_client_looks_empty(vgraph, client))
{
ladish_del_ref(client);
return false;
}
ASSERT(ladish_graph_client_is_hidden(vgraph, vclient)); /* vclients are automatically hidden when they start looking empty (on port disappear) */
ASSERT(ladish_graph_client_is_hidden(vgraph, client)); /* vclients are automatically hidden when they start looking empty (on port disappear) */
ladish_del_ref(client);
return true;
}
@ -1395,8 +1412,9 @@ remove_app_port(
ladish_graph_get_port_name(vgraph, port_handle),
ladish_graph_get_description(vgraph));
ladish_graph_remove_port(graph_handle, port_handle);
ladish_graph_remove_port(vgraph, port_handle);
ladish_graph_remove_port(graph_handle, port_handle, NULL);
ladish_graph_remove_port(vgraph, port_handle, NULL);
ladish_del_ref(vclient);
return true;
}
@ -1409,10 +1427,9 @@ ladish_virtualizer_remove_app(
const uuid_t app_uuid,
const char * app_name)
{
ladish_client_handle jclient;
ladish_client_handle client;
ladish_graph_handle vgraph;
uuid_t vclient_uuid;
ladish_client_handle vclient;
bool is_empty;
struct app_remove_context ctx;
@ -1423,19 +1440,20 @@ ladish_virtualizer_remove_app(
ladish_graph_iterate_nodes(jack_graph, &ctx, NULL, remove_app_port, NULL);
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (jclient == NULL)
client = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (client == NULL)
{
log_info("removing app without JACK client");
return;
}
ASSERT(!ladish_virtualizer_is_a2j_client(jclient)); /* a2j client has no app associated */
ASSERT(!ladish_virtualizer_is_a2j_client(client)); /* a2j client has no app associated */
vgraph = ladish_client_get_vgraph(jclient);
vgraph = ladish_client_get_vgraph(client);
if (vgraph == NULL)
{
ASSERT_NO_PASS;
ladish_del_ref(client);
return;
}
@ -1444,12 +1462,13 @@ ladish_virtualizer_remove_app(
/* check whether the client is empty because this cannot
be checked later because the client was removed
(see where is_empty is used) */
is_empty = ladish_graph_client_is_empty(jack_graph, jclient);
is_empty = ladish_graph_client_is_empty(jack_graph, client);
ladish_graph_remove_client(jack_graph, jclient);
ladish_graph_remove_client(jack_graph, client);
if (!ladish_client_get_interlink(jclient, vclient_uuid))
if (!ladish_client_get_interlink(client, vclient_uuid))
{
ladish_del_ref(client);
if (is_empty)
{
/* jack client without ports and thus without vgraph client */
@ -1463,16 +1482,18 @@ ladish_virtualizer_remove_app(
return;
}
vclient = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid);
if (vclient == NULL)
ladish_del_ref(client);
client = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid);
if (client == NULL)
{
ASSERT_NO_PASS;
return;
}
ladish_graph_remove_client(vgraph, vclient);
ladish_graph_remove_client(vgraph, client);
ladish_graph_dump(g_studio.jack_graph);
ladish_graph_dump(vgraph);
ladish_del_ref(client);
}
void
@ -1501,12 +1522,14 @@ ladish_virtualizer_rename_app(
if (client != NULL)
{
ladish_graph_rename_client(vgraph, client, new_app_name);
ladish_del_ref(client);
}
client = ladish_graph_find_client_by_app(g_studio.jack_graph, uuid);
if (client != NULL)
{
ladish_graph_rename_client(g_studio.jack_graph, client, new_app_name);
ladish_del_ref(client);
}
}
#undef vgraph
@ -1564,12 +1587,13 @@ bool ladish_virtualizer_split_client(ladish_graph_handle vgraph, uint64_t client
ladish_client_handle vclient1;
ladish_client_handle vclient2;
const char * name;
bool ret = false;
vclient1 = ladish_graph_find_client_by_id(vgraph, client_id);
if (vclient1 == NULL)
{
log_error("Cannot find client %"PRIu64" in %s", client_id, ladish_graph_get_description(vgraph));
return false;
goto exit;
}
name = ladish_graph_get_client_name(vgraph, vclient1);
@ -1577,7 +1601,7 @@ bool ladish_virtualizer_split_client(ladish_graph_handle vgraph, uint64_t client
if (!ladish_client_create(NULL, &vclient2))
{
log_error("ladish_client_create() failed.");
return false;
goto unref_vclient1;
}
ladish_client_interlink_copy(vclient2, vclient1);
@ -1586,11 +1610,17 @@ bool ladish_virtualizer_split_client(ladish_graph_handle vgraph, uint64_t client
if (!ladish_graph_add_client(vgraph, vclient2, name, false))
{
log_error("ladish_graph_add_client() failed to add client '%s' to virtual graph", name);
ladish_client_destroy(vclient2);
return false;
goto unref_vclient2;
}
return ladish_graph_interate_client_ports(vgraph, vclient1, vclient2, move_capture_port_callback);
ret = ladish_graph_interate_client_ports(vgraph, vclient1, vclient2, move_capture_port_callback);
unref_vclient2:
ladish_del_ref(vclient2);
unref_vclient1:
ladish_del_ref(vclient1);
exit:
return ret;
}
static
@ -1637,6 +1667,7 @@ ladish_virtualizer_join_clients(
if (vclient2 == NULL)
{
log_error("Cannot find client %"PRIu64" in %s", client2_id, ladish_graph_get_description(vgraph));
ladish_del_ref(vclient1);
return false;
}
@ -1644,5 +1675,7 @@ ladish_virtualizer_join_clients(
ladish_graph_remove_client(vgraph, vclient2);
ladish_del_ref(vclient2);
ladish_del_ref(vclient1);
return true;
}