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) * 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 * This file contains the implementation of the client objects
@ -29,6 +29,7 @@
struct ladish_client struct ladish_client
{ {
ladish_object obj;
uuid_t uuid; /* The UUID of the client */ uuid_t uuid; /* The UUID of the client */
uuid_t uuid_interlink; /* The UUID of the linked client (vgraph <-> jack graph) */ 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 */ uuid_t uuid_app; /* The UUID of the app that owns this client */
@ -40,6 +41,8 @@ struct ladish_client
void * vgraph; /* virtual graph */ void * vgraph; /* virtual graph */
}; };
static void ladish_client_destroy(ladish_client_handle client_handle);
bool bool
ladish_client_create( ladish_client_create(
const uuid_t uuid_ptr, const uuid_t uuid_ptr,
@ -73,6 +76,8 @@ ladish_client_create(
uuid_clear(client_ptr->uuid_interlink); uuid_clear(client_ptr->uuid_interlink);
uuid_clear(client_ptr->uuid_app); 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_id = 0;
client_ptr->jack_name = NULL; client_ptr->jack_name = NULL;
client_ptr->pid = 0; client_ptr->pid = 0;
@ -102,9 +107,7 @@ ladish_client_create_copy(
return ladish_client_create(client_ptr->uuid, client_handle_ptr); return ladish_client_create(client_ptr->uuid, client_handle_ptr);
} }
void static void ladish_client_destroy(ladish_client_handle client_handle)
ladish_client_destroy(
ladish_client_handle client_handle)
{ {
log_info("client %p destroy", client_ptr); log_info("client %p destroy", client_ptr);

View File

@ -2,7 +2,7 @@
/* /*
* LADI Session Handler (ladish) * 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 * 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,
ladish_client_handle * client_handle_ptr); 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); 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); 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); log_error("ladish_graph_add_client() failed to add client '%s' to JACK graph", name_dup);
context_ptr->error = XML_TRUE; context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client); ladish_del_ref(context_ptr->client);
context_ptr->client = NULL; context_ptr->client = NULL;
goto free; 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); log_error("ladish_graph_add_client() failed to add client '%s' to studio graph", name_dup);
context_ptr->error = XML_TRUE; context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client); ladish_del_ref(context_ptr->client);
context_ptr->client = NULL; context_ptr->client = NULL;
goto free; goto free;
} }
@ -834,6 +834,7 @@ static void callback_elend(void * data, const char * UNUSED(el))
{ {
//log_info("</client>"); //log_info("</client>");
ASSERT(context_ptr->client != NULL); ASSERT(context_ptr->client != NULL);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL; context_ptr->client = NULL;
} }
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_PORT) 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)) 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); 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)) if (!ladish_client_create(ladish_wkclient_playback, &playback))
{ {
log_error("ladish_client_create() failed to create playback client to room template \"%s\".", name); 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)) 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); 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); room_descriptor_ptr->name = ladish_room_get_name(room);
@ -257,6 +257,8 @@ create_room_template(
return true; return true;
fail_unref_capture:
ladish_del_ref(capture);
fail_destroy: fail_destroy:
ladish_room_destroy(room); /* this will destroy the graph clients as well */ ladish_room_destroy(room); /* this will destroy the graph clients as well */
fail: fail:

View File

@ -1239,7 +1239,7 @@ ladish_graph_remove_port_internal(
{ {
ladish_graph_remove_port_connections(graph_ptr, port_ptr); 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_client);
list_del(&port_ptr->siblings_graph); list_del(&port_ptr->siblings_graph);
@ -1260,7 +1260,6 @@ void
ladish_graph_remove_client_internal( ladish_graph_remove_client_internal(
struct ladish_graph * graph_ptr, struct ladish_graph * graph_ptr,
struct ladish_graph_client * client_ptr, struct ladish_graph_client * client_ptr,
bool destroy_client,
ladish_graph_simple_port_callback port_callback) ladish_graph_simple_port_callback port_callback)
{ {
struct ladish_graph_port * port_ptr; struct ladish_graph_port * port_ptr;
@ -1285,10 +1284,7 @@ ladish_graph_remove_client_internal(
free(client_ptr->name); free(client_ptr->name);
if (destroy_client) ladish_del_ref(client_ptr->client);
{
ladish_client_destroy(client_ptr->client);
}
free(client_ptr); 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)) while (!list_empty(&graph_ptr->clients))
{ {
client_ptr = list_entry(graph_ptr->clients.next, struct ladish_graph_client, siblings); 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++; client_ptr->id = graph_ptr->next_client_id++;
ladish_add_ref(client_handle);
client_ptr->client = client_handle; client_ptr->client = client_handle;
client_ptr->hidden = hidden; client_ptr->hidden = hidden;
graph_ptr->graph_version++; graph_ptr->graph_version++;
@ -1553,7 +1550,7 @@ ladish_graph_remove_client(
client_ptr = ladish_graph_find_client(graph_ptr, client_handle); client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
if (client_ptr != NULL) 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 else
{ {
@ -1625,7 +1622,7 @@ ladish_graph_add_port(
port_ptr->id = graph_ptr->next_port_id++; port_ptr->id = graph_ptr->next_port_id++;
port_ptr->port = port_handle; port_ptr->port = port_handle;
ladish_port_add_ref(port_ptr->port); ladish_add_ref(port_ptr->port);
port_ptr->hidden = true; port_ptr->hidden = true;
port_ptr->link = ladish_port_is_link(port_handle); 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 && 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 */ (!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; 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) if (uuid_compare(current_uuid, app_uuid) == 0)
{ {
ladish_add_ref(client_ptr->client);
return 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); ladish_client_get_uuid(client_ptr->client, current_uuid);
if (uuid_compare(current_uuid, uuid) == 0) if (uuid_compare(current_uuid, uuid) == 0)
{ {
ladish_add_ref(client_ptr->client);
return 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; return NULL;
} }
ladish_add_ref(port_ptr->client_ptr->client);
return 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); client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
if (client_ptr->id == client_id) if (client_ptr->id == client_id)
{ {
ladish_add_ref(client_ptr->client);
return 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); client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
if (ladish_client_get_jack_id(client_ptr->client) == client_id) if (ladish_client_get_jack_id(client_ptr->client) == client_id)
{ {
ladish_add_ref(client_ptr->client);
return 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; return false;
} }
ladish_client_handle bool
ladish_graph_remove_port( ladish_graph_remove_port(
ladish_graph_handle graph_handle, ladish_graph_handle graph_handle,
ladish_port_handle port) ladish_port_handle port,
ladish_client_handle * client_ptr)
{ {
struct ladish_graph_port * port_ptr; struct ladish_graph_port * port_ptr;
ladish_client_handle client; ladish_client_handle client;
@ -2061,15 +2065,23 @@ ladish_graph_remove_port(
port_ptr = ladish_graph_find_port(graph_ptr, port); port_ptr = ladish_graph_find_port(graph_ptr, port);
if (port_ptr == NULL) if (port_ptr == NULL)
{ {
return NULL; return false;
} }
client = port_ptr->client_ptr->client; client = port_ptr->client_ptr->client;
ASSERT(client != NULL);
ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr); 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_remove_port_by_jack_id(
ladish_graph_handle graph_handle, ladish_graph_handle graph_handle,
uint64_t jack_port_id, uint64_t jack_port_id,
@ -2077,17 +2089,14 @@ ladish_graph_remove_port_by_jack_id(
bool studio) bool studio)
{ {
struct ladish_graph_port * port_ptr; 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); port_ptr = ladish_graph_find_port_by_jack_id_internal(graph_ptr, jack_port_id, room, studio);
if (port_ptr == NULL) 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); ladish_graph_remove_port_internal(graph_ptr, port_ptr->client_ptr, port_ptr);
return client;
} }
void 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); client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings);
if (client_ptr->hidden) 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)) if (!ladish_graph_add_client(context, copy, client_name, false))
{ {
ladish_client_destroy(copy); ladish_del_ref(copy);
return false; return false;
} }
@ -3000,6 +3009,20 @@ ladish_graph_copy_client_begin_callback(
return true; 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 static
bool bool
ladish_graph_copy_port_callback( ladish_graph_copy_port_callback(
@ -3039,7 +3062,7 @@ bool ladish_graph_copy(ladish_graph_handle src, ladish_graph_handle dest)
dest, dest,
ladish_graph_copy_client_begin_callback, ladish_graph_copy_client_begin_callback,
ladish_graph_copy_port_callback, ladish_graph_copy_port_callback,
NULL); ladish_graph_copy_client_end_callback);
} }
CDBUS_METHOD_ARGS_BEGIN(GetAllPorts, "Get all ports") CDBUS_METHOD_ARGS_BEGIN(GetAllPorts, "Get all ports")

View File

@ -2,7 +2,7 @@
/* /*
* LADI Session Handler (ladish) * 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 * This file contains interface to the D-Bus patchbay interface helpers
@ -90,12 +90,13 @@ ladish_graph_add_port(
uint32_t flags, uint32_t flags,
bool hidden); bool hidden);
ladish_client_handle bool
ladish_graph_remove_port( ladish_graph_remove_port(
ladish_graph_handle graph_handle, 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_remove_port_by_jack_id(
ladish_graph_handle graph_handle, ladish_graph_handle graph_handle,
uint64_t jack_port_id, uint64_t jack_port_id,

View File

@ -2,7 +2,7 @@
/* /*
* LADI Session Handler (ladish) * 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 * 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; return false;
} }
*dict_handle_ptr = ladish_client_get_dict(client); *dict_handle_ptr = ladish_client_get_dict(client);
ladish_del_ref(client);
return true; return true;
case GRAPH_DICT_OBJECT_TYPE_PORT: case GRAPH_DICT_OBJECT_TYPE_PORT:
port = ladish_graph_find_port_by_id(graph_handle, object_id); port = ladish_graph_find_port_by_id(graph_handle, object_id);

View File

@ -2,7 +2,7 @@
/* /*
* LADI Session Handler (ladish) * 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 * 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); 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) 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_graph_move_port(graph, port, client);
ladish_del_ref(client);
cdbus_method_return_new_void(call_ptr); 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)) 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); 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; return;
} }
client_id = ladish_graph_get_client_id(graph, client); 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); 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)) if (ladish_graph_client_has_visible_ports(graph, client))
{ {
cdbus_error(call_ptr, DBUS_ERROR_INVALID_ARGS, "Cannot remove non-empty client"); cdbus_error(call_ptr, DBUS_ERROR_INVALID_ARGS, "Cannot remove non-empty client");
ladish_del_ref(client);
return; return;
} }
ladish_graph_remove_client(graph, client); ladish_graph_remove_client(graph, client);
ladish_del_ref(client);
cdbus_method_return_new_void(call_ptr); 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_app(jclient, app_uuid);
ladish_client_set_vgraph(jclient, ctx_ptr->vgraph); ladish_client_set_vgraph(jclient, ctx_ptr->vgraph);
ladish_del_ref(vclient);
return true; return true;
} }

View File

@ -2,7 +2,7 @@
/* /*
* LADI Session Handler (ladish) * 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 * This file contains the implementation of the port objects
@ -29,7 +29,7 @@
/* JACK port */ /* JACK port */
struct ladish_port struct ladish_port
{ {
int refcount; ladish_object obj;
uuid_t uuid; /* The UUID of the port */ uuid_t uuid; /* The UUID of the port */
uuid_t app_uuid; /* The UUID of the app that owns this client */ uuid_t app_uuid; /* The UUID of the app that owns this client */
bool link; /* Whether the port is studio-room link port */ bool link; /* Whether the port is studio-room link port */
@ -76,10 +76,11 @@ ladish_port_create(
uuid_clear(port_ptr->app_uuid); 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 = 0;
port_ptr->jack_id_room = 0; port_ptr->jack_id_room = 0;
port_ptr->link = link; port_ptr->link = link;
port_ptr->refcount = 0;
port_ptr->vgraph = NULL; 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) void ladish_port_destroy(ladish_port_handle port_handle)
{ {
log_info("port %p destroy", port_ptr); log_info("port %p destroy", port_ptr);
ASSERT(port_ptr->refcount == 0); ASSERT(port_ptr->obj.refcount == 0);
ladish_dict_destroy(port_ptr->dict); ladish_dict_destroy(port_ptr->dict);
free(port_ptr); 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) bool ladish_port_is_link(ladish_port_handle port_handle)
{ {
return port_ptr->link; return port_ptr->link;

View File

@ -2,7 +2,7 @@
/* /*
* LADI Session Handler (ladish) * 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 * 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); 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); 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); bool ladish_port_is_link(ladish_port_handle port_handle);
void ladish_port_set_vgraph(ladish_port_handle port_handle, void * vgraph); 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_graph = ladish_studio_get_jack_graph();
jack_client = ladish_graph_remove_port(jack_graph, port); if (!ladish_graph_remove_port(jack_graph, port, &jack_client))
if (jack_client == NULL)
{ /* room app port not found in jack graph */ { /* room app port not found in jack graph */
/* this can happen if the port is hidden in the vgraph */ /* this can happen if the port is hidden in the vgraph */
return; return;
@ -256,6 +255,8 @@ static void remove_port_callback(ladish_port_handle port)
{ {
ladish_graph_remove_client(jack_graph, jack_client); ladish_graph_remove_client(jack_graph, jack_client);
} }
ladish_del_ref(jack_client);
} }
bool bool
@ -342,7 +343,7 @@ ladish_room_create(
if (!ladish_graph_add_client(owner, room_ptr->client, room_ptr->name, true)) 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."); 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)) 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; goto remove_client;
} }
ladish_del_ref(room_ptr->client);
ladish_studio_room_appeared((ladish_room_handle)room_ptr); ladish_studio_room_appeared((ladish_room_handle)room_ptr);
*room_handle_ptr = (ladish_room_handle)room_ptr; *room_handle_ptr = (ladish_room_handle)room_ptr;
@ -358,8 +361,8 @@ ladish_room_create(
remove_client: remove_client:
ladish_graph_remove_client(owner, room_ptr->client); ladish_graph_remove_client(owner, room_ptr->client);
destroy_client: unref_client:
ladish_client_destroy(room_ptr->client); ladish_del_ref(room_ptr->client);
unregister_dbus_object: unregister_dbus_object:
cdbus_object_path_unregister(cdbus_g_dbus_connection, room_ptr->dbus_object); cdbus_object_path_unregister(cdbus_g_dbus_connection, room_ptr->dbus_object);
destroy_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_app_supervisor_destroy(room_ptr->app_supervisor);
ladish_graph_remove_client(room_ptr->owner, room_ptr->client); 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_room_disappeared((ladish_room_handle)room_ptr);
ladish_studio_release_room_index(room_ptr->index); ladish_studio_release_room_index(room_ptr->index);
@ -742,9 +745,9 @@ ladish_room_add_port(
ladish_port_handle port; ladish_port_handle port;
bool playback; bool playback;
ladish_client_handle client; ladish_client_handle client;
ladish_client_handle client2;
const char * client_name; const char * client_name;
uuid_t client_uuid; uuid_t client_uuid;
bool new_client;
playback = port_is_input(flags); 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 */ /* if client is not found, create it and add it to graph */
client = ladish_graph_find_client_by_uuid(room_ptr->graph, client_uuid); client = ladish_graph_find_client_by_uuid(room_ptr->graph, client_uuid);
new_client = client == NULL; if (client == NULL)
if (new_client)
{ {
if (!ladish_client_create(client_uuid, &client)) 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)) 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"); 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)) 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); 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)) if (!create_shadow_port(room_ptr, port, name, type, flags))
@ -788,19 +790,21 @@ ladish_room_add_port(
goto fail_remove_port; goto fail_remove_port;
} }
ladish_del_ref(client);
return port; return port;
fail_remove_port: fail_remove_port:
ASSERT(client != NULL); 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; ASSERT_NO_PASS;
} }
fail_destroy_client: if (client2 != client)
if (new_client)
{ {
ladish_client_destroy(client); ASSERT_NO_PASS;
} }
fail_unref_client:
ladish_del_ref(client);
fail_destroy_port: fail_destroy_port:
ladish_port_destroy(port); ladish_port_destroy(port);
fail: 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); log_error("ladish_graph_add_client() failed to add client '%s' to JACK graph", name_dup);
context_ptr->error = XML_TRUE; context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client); ladish_del_ref(context_ptr->client);
context_ptr->client = NULL; 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); log_error("ladish_graph_add_client() failed to add client '%s' to room graph", name_dup);
context_ptr->error = XML_TRUE; context_ptr->error = XML_TRUE;
ladish_client_destroy(context_ptr->client); ladish_del_ref(context_ptr->client);
context_ptr->client = NULL; context_ptr->client = NULL;
} }
@ -711,6 +711,7 @@ static void callback_elend(void * data, const char * UNUSED(el))
{ {
//log_info("</client>"); //log_info("</client>");
ASSERT(context_ptr->client != NULL); ASSERT(context_ptr->client != NULL);
ladish_del_ref(context_ptr->client);
context_ptr->client = NULL; context_ptr->client = NULL;
} }
else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_PORT) 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) if (ladish_client_get_jack_id(client) != 0)
{ {
log_error("Ignoring client with duplicate name '%s' ('%s')", name, jack_name); 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); 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)) 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); log_error("ladish_graph_add_client() failed to add client %"PRIu64" (%s) to JACK graph", id, name);
ladish_client_destroy(client); goto unref_client;
goto exit;
} }
done: done:
@ -409,6 +408,8 @@ done:
ladish_client_set_vgraph(client, g_studio.studio_graph); ladish_client_set_vgraph(client, g_studio.studio_graph);
} }
unref_client:
ladish_del_ref(client);
exit: exit:
return; return;
} }
@ -497,10 +498,11 @@ static void client_disappeared(void * context, uint64_t id)
else else
{ {
ladish_graph_remove_client(virtualizer_ptr->jack_graph, client); 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 /* 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) */ * it will be destroyed before it is accessed (persist flag is cleared on room deletion) */
} }
ladish_del_ref(client);
} }
static static
@ -569,7 +571,7 @@ port_appeared(
if (vgraph == NULL) if (vgraph == NULL)
{ {
log_error("Cannot find vgraph for appeared jmcore port '%s'", real_jack_port_name); log_error("Cannot find vgraph for appeared jmcore port '%s'", real_jack_port_name);
goto exit; goto unref_jack_client;
} }
/* jmcore port appeared */ /* 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)) 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."); log_error("ladish_graph_add_port() failed.");
goto exit; goto unref_jack_client;
} }
if (vgraph == g_studio.studio_graph) 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)); log_error("link port client not found in vgraph %s", ladish_graph_get_description(vgraph));
ASSERT_NO_PASS; ASSERT_NO_PASS;
goto exit; goto unref_jack_client;
} }
ladish_graph_show_port(vgraph, port); ladish_graph_show_port(vgraph, port);
goto exit; ladish_del_ref(vclient);
goto unref_jack_client;
} }
else else
{ {
@ -620,7 +623,7 @@ port_appeared(
if (alsa_client_name == NULL) if (alsa_client_name == NULL)
{ {
log_error("catdup failed to duplicate a2j jack client name after map failure"); 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); 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"); log_error("catdup failed to duplicate a2j jack port name after map failure");
free(alsa_client_name); free(alsa_client_name);
goto exit; goto unref_jack_client;
} }
vclient_name = alsa_client_name; vclient_name = alsa_client_name;
@ -723,6 +726,7 @@ port_appeared(
ladish_client_set_jack_id(vclient, client_id); ladish_client_set_jack_id(vclient, client_id);
ladish_graph_adjust_port(vgraph, port, type, flags); ladish_graph_adjust_port(vgraph, port, type, flags);
ladish_graph_show_port(vgraph, port); ladish_graph_show_port(vgraph, port);
ladish_del_ref(vclient);
goto free_alsa_names; goto free_alsa_names;
} }
@ -775,8 +779,7 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, vclient_name, false)) if (!ladish_graph_add_client(vgraph, vclient, vclient_name, false))
{ {
log_error("ladish_graph_add_client() failed."); log_error("ladish_graph_add_client() failed.");
ladish_client_destroy(vclient); goto unref_vclient;
goto free_alsa_names;
} }
} }
} }
@ -799,8 +802,7 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, "Hardware Capture", false)) if (!ladish_graph_add_client(vgraph, vclient, "Hardware Capture", false))
{ {
log_error("ladish_graph_add_client() failed."); log_error("ladish_graph_add_client() failed.");
ladish_client_destroy(vclient); goto unref_vclient;
goto free_alsa_names;
} }
} }
} }
@ -817,8 +819,8 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, "Hardware Playback", false)) if (!ladish_graph_add_client(vgraph, vclient, "Hardware Playback", false))
{ {
ladish_client_destroy(vclient); log_error("ladish_graph_add_client() failed.");
goto free_alsa_names; goto unref_vclient;
} }
} }
} }
@ -868,8 +870,7 @@ port_appeared(
if (!ladish_graph_add_client(vgraph, vclient, vclient_name, false)) 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); log_error("ladish_graph_add_client() failed to add client '%s' to virtual graph", jack_client_name);
ladish_client_destroy(vclient); goto unref_vclient;
goto free_alsa_names;
} }
} }
else else
@ -896,14 +897,17 @@ port_appeared(
if (!ladish_graph_add_port(vgraph, vclient, port, vport_name, type, flags, false)) if (!ladish_graph_add_port(vgraph, vclient, port, vport_name, type, flags, false))
{ {
log_error("ladish_graph_add_port() failed."); log_error("ladish_graph_add_port() failed.");
goto free_alsa_names;
} }
unref_vclient:
ladish_del_ref(vclient);
free_alsa_names: free_alsa_names:
free(a2j_fake_jack_port_name); free(a2j_fake_jack_port_name);
free(alsa_client_name); free(alsa_client_name);
free(alsa_port_name); free(alsa_port_name);
unref_jack_client:
ladish_del_ref(jack_client);
exit: exit:
return; return;
} }
@ -951,6 +955,7 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i
if (port == NULL) if (port == NULL)
{ {
log_error("Unknown JACK port with id %"PRIu64" disappeared", port_id); log_error("Unknown JACK port with id %"PRIu64" disappeared", port_id);
ladish_del_ref(jclient);
return; 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"); log_error("Cannot find vgraph for disappeared jmcore port");
ASSERT_NO_PASS; ASSERT_NO_PASS;
ladish_del_ref(jclient);
return; 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_graph_hide_client(vgraph, vclient);
} }
ladish_del_ref(vclient);
} }
} }
else else
{ {
if (!jmcore) if (!jmcore)
{ {
ladish_graph_remove_port(virtualizer_ptr->jack_graph, port); ladish_graph_remove_port(virtualizer_ptr->jack_graph, port, NULL);
} }
if (vgraph != NULL) if (vgraph != NULL)
{ {
vclient = ladish_graph_remove_port(vgraph, port); if (ladish_graph_remove_port(vgraph, port, &vclient))
if (vclient != NULL)
{ {
if (ladish_graph_client_is_empty(vgraph, vclient)) if (ladish_graph_client_is_empty(vgraph, vclient))
{ {
ladish_graph_remove_client(vgraph, vclient); ladish_graph_remove_client(vgraph, vclient);
ladish_client_clear_interlink(jclient); ladish_client_clear_interlink(jclient);
} }
ladish_del_ref(vclient);
} }
} }
} }
ladish_del_ref(jclient);
} }
static 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) static bool app_has_a2j_ports(ladish_graph_handle jack_graph, const uuid_t app_uuid)
{ {
ladish_client_handle a2jclient; ladish_client_handle a2jclient;
bool ret;
a2jclient = ladish_graph_find_client_by_uuid(jack_graph, g_a2j_uuid); a2jclient = ladish_graph_find_client_by_uuid(jack_graph, g_a2j_uuid);
if (a2jclient == NULL) 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 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 bool
@ -1270,10 +1282,9 @@ ladish_virtualizer_is_hidden_app(
const uuid_t app_uuid, const uuid_t app_uuid,
const char * app_name) const char * app_name)
{ {
ladish_client_handle jclient; ladish_client_handle client;
ladish_graph_handle vgraph; ladish_graph_handle vgraph;
uuid_t vclient_uuid; uuid_t vclient_uuid;
ladish_client_handle vclient;
//ladish_graph_dump(g_studio.jack_graph); //ladish_graph_dump(g_studio.jack_graph);
@ -1283,33 +1294,35 @@ ladish_virtualizer_is_hidden_app(
return false; return false;
} }
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid); client = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (jclient == NULL) if (client == NULL)
{ {
log_info("App without JACK client is treated as hidden one"); log_info("App without JACK client is treated as hidden one");
return true; 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) if (vgraph == NULL)
{ {
ASSERT_NO_PASS; ASSERT_NO_PASS;
ladish_del_ref(client);
return true; return true;
} }
//ladish_graph_dump(vgraph); //ladish_graph_dump(vgraph);
if (!ladish_graph_client_looks_empty(jack_graph, jclient) || if (!ladish_graph_client_looks_empty(jack_graph, client) ||
!ladish_graph_client_is_hidden(jack_graph, jclient)) !ladish_graph_client_is_hidden(jack_graph, client))
{ {
ladish_del_ref(client);
return false; 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); 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); log_error("jack client of app '%s' has no interlinked vgraph client", app_name);
ASSERT_NO_PASS; ASSERT_NO_PASS;
} }
ladish_del_ref(client);
return true; return true;
} }
vclient = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid); ladish_del_ref(client);
if (vclient == NULL) client = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid);
if (client == NULL)
{ {
ASSERT_NO_PASS; ASSERT_NO_PASS;
return true; return true;
} }
if (!ladish_graph_client_looks_empty(vgraph, vclient)) if (!ladish_graph_client_looks_empty(vgraph, client))
{ {
ladish_del_ref(client);
return false; 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; return true;
} }
@ -1395,8 +1412,9 @@ remove_app_port(
ladish_graph_get_port_name(vgraph, port_handle), ladish_graph_get_port_name(vgraph, port_handle),
ladish_graph_get_description(vgraph)); ladish_graph_get_description(vgraph));
ladish_graph_remove_port(graph_handle, port_handle); ladish_graph_remove_port(graph_handle, port_handle, NULL);
ladish_graph_remove_port(vgraph, port_handle); ladish_graph_remove_port(vgraph, port_handle, NULL);
ladish_del_ref(vclient);
return true; return true;
} }
@ -1409,10 +1427,9 @@ ladish_virtualizer_remove_app(
const uuid_t app_uuid, const uuid_t app_uuid,
const char * app_name) const char * app_name)
{ {
ladish_client_handle jclient; ladish_client_handle client;
ladish_graph_handle vgraph; ladish_graph_handle vgraph;
uuid_t vclient_uuid; uuid_t vclient_uuid;
ladish_client_handle vclient;
bool is_empty; bool is_empty;
struct app_remove_context ctx; 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); ladish_graph_iterate_nodes(jack_graph, &ctx, NULL, remove_app_port, NULL);
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid); client = ladish_graph_find_client_by_app(jack_graph, app_uuid);
if (jclient == NULL) if (client == NULL)
{ {
log_info("removing app without JACK client"); log_info("removing app without JACK client");
return; 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) if (vgraph == NULL)
{ {
ASSERT_NO_PASS; ASSERT_NO_PASS;
ladish_del_ref(client);
return; return;
} }
@ -1444,12 +1462,13 @@ ladish_virtualizer_remove_app(
/* check whether the client is empty because this cannot /* check whether the client is empty because this cannot
be checked later because the client was removed be checked later because the client was removed
(see where is_empty is used) */ (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) if (is_empty)
{ {
/* jack client without ports and thus without vgraph client */ /* jack client without ports and thus without vgraph client */
@ -1463,16 +1482,18 @@ ladish_virtualizer_remove_app(
return; return;
} }
vclient = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid); ladish_del_ref(client);
if (vclient == NULL) client = ladish_graph_find_client_by_uuid(vgraph, vclient_uuid);
if (client == NULL)
{ {
ASSERT_NO_PASS; ASSERT_NO_PASS;
return; return;
} }
ladish_graph_remove_client(vgraph, vclient); ladish_graph_remove_client(vgraph, client);
ladish_graph_dump(g_studio.jack_graph); ladish_graph_dump(g_studio.jack_graph);
ladish_graph_dump(vgraph); ladish_graph_dump(vgraph);
ladish_del_ref(client);
} }
void void
@ -1501,12 +1522,14 @@ ladish_virtualizer_rename_app(
if (client != NULL) if (client != NULL)
{ {
ladish_graph_rename_client(vgraph, client, new_app_name); 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); client = ladish_graph_find_client_by_app(g_studio.jack_graph, uuid);
if (client != NULL) if (client != NULL)
{ {
ladish_graph_rename_client(g_studio.jack_graph, client, new_app_name); ladish_graph_rename_client(g_studio.jack_graph, client, new_app_name);
ladish_del_ref(client);
} }
} }
#undef vgraph #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 vclient1;
ladish_client_handle vclient2; ladish_client_handle vclient2;
const char * name; const char * name;
bool ret = false;
vclient1 = ladish_graph_find_client_by_id(vgraph, client_id); vclient1 = ladish_graph_find_client_by_id(vgraph, client_id);
if (vclient1 == NULL) if (vclient1 == NULL)
{ {
log_error("Cannot find client %"PRIu64" in %s", client_id, ladish_graph_get_description(vgraph)); 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); 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)) if (!ladish_client_create(NULL, &vclient2))
{ {
log_error("ladish_client_create() failed."); log_error("ladish_client_create() failed.");
return false; goto unref_vclient1;
} }
ladish_client_interlink_copy(vclient2, 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)) if (!ladish_graph_add_client(vgraph, vclient2, name, false))
{ {
log_error("ladish_graph_add_client() failed to add client '%s' to virtual graph", name); log_error("ladish_graph_add_client() failed to add client '%s' to virtual graph", name);
ladish_client_destroy(vclient2); goto unref_vclient2;
return false;
} }
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 static
@ -1637,6 +1667,7 @@ ladish_virtualizer_join_clients(
if (vclient2 == NULL) if (vclient2 == NULL)
{ {
log_error("Cannot find client %"PRIu64" in %s", client2_id, ladish_graph_get_description(vgraph)); log_error("Cannot find client %"PRIu64" in %s", client2_id, ladish_graph_get_description(vgraph));
ladish_del_ref(vclient1);
return false; return false;
} }
@ -1644,5 +1675,7 @@ ladish_virtualizer_join_clients(
ladish_graph_remove_client(vgraph, vclient2); ladish_graph_remove_client(vgraph, vclient2);
ladish_del_ref(vclient2);
ladish_del_ref(vclient1);
return true; return true;
} }