diff --git a/daemon/client.c b/daemon/client.c index 0a962b11..0c9de964 100644 --- a/daemon/client.c +++ b/daemon/client.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov * ************************************************************************** * 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); diff --git a/daemon/client.h b/daemon/client.h index fe8e83a4..8d16b1d0 100644 --- a/daemon/client.h +++ b/daemon/client.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov * ************************************************************************** * 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); diff --git a/daemon/cmd_load_studio.c b/daemon/cmd_load_studio.c index c43c0962..3538a5a7 100644 --- a/daemon/cmd_load_studio.c +++ b/daemon/cmd_load_studio.c @@ -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(""); 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) diff --git a/daemon/control.c b/daemon/control.c index 9d2ab142..350d9ad3 100644 --- a/daemon/control.c +++ b/daemon/control.c @@ -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: diff --git a/daemon/graph.c b/daemon/graph.c index 3e9f5c3b..1326b29b 100644 --- a/daemon/graph.c +++ b/daemon/graph.c @@ -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") diff --git a/daemon/graph.h b/daemon/graph.h index 9730b203..a9ef368c 100644 --- a/daemon/graph.h +++ b/daemon/graph.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov * ************************************************************************** * 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, diff --git a/daemon/graph_dict.c b/daemon/graph_dict.c index 5a8715e2..2e9961c0 100644 --- a/daemon/graph_dict.c +++ b/daemon/graph_dict.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009,2010,2011 Nedko Arnaudov + * Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov * ************************************************************************** * 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); diff --git a/daemon/graph_manager.c b/daemon/graph_manager.c index 50348b59..73011174 100644 --- a/daemon/graph_manager.c +++ b/daemon/graph_manager.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2011 Nedko Arnaudov + * Copyright (C) 2011,2012 Nedko Arnaudov * ************************************************************************** * 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); } diff --git a/daemon/load.c b/daemon/load.c index 77e34fea..6d318c2c 100644 --- a/daemon/load.c +++ b/daemon/load.c @@ -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; } diff --git a/daemon/port.c b/daemon/port.c index 6b81ad0a..ec59089f 100644 --- a/daemon/port.c +++ b/daemon/port.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov * ************************************************************************** * 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; diff --git a/daemon/port.h b/daemon/port.h index 1eb3e126..a78ed1e0 100644 --- a/daemon/port.h +++ b/daemon/port.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009,2010,2011,2012 Nedko Arnaudov * ************************************************************************** * 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); diff --git a/daemon/room.c b/daemon/room.c index ac97ec7d..5dd5e912 100644 --- a/daemon/room.c +++ b/daemon/room.c @@ -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: diff --git a/daemon/room_load.c b/daemon/room_load.c index de00a3ab..2bb4030a 100644 --- a/daemon/room_load.c +++ b/daemon/room_load.c @@ -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(""); 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) diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index dfa25aa2..a97e7f97 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -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; }