From 76a8b6161b95cef599866f2c8a4d9eed01ffa0b6 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Mon, 30 Aug 2010 00:05:57 +0300 Subject: [PATCH] daemon: handle apps with same name in different vgraphs --- daemon/app_supervisor.c | 60 ++++++++++++++++++++--------------------- daemon/app_supervisor.h | 49 ++++++++++++++++++--------------- daemon/client.c | 23 ++++++++++++++++ daemon/client.h | 4 +++ daemon/cmd_change_app_state.c | 4 ++- daemon/cmd_new_app.c | 2 +- daemon/cmd_remove_app.c | 4 ++- daemon/graph.c | 34 +++++++++++++++++++++-- daemon/graph.h | 3 ++- daemon/load.c | 63 ++++++++++++++++++++++++++++++++++--------- daemon/load.h | 2 +- daemon/room.c | 5 ++-- daemon/room_load.c | 2 +- daemon/save.c | 12 ++++++++- daemon/studio.c | 9 +++++-- daemon/studio.h | 1 + daemon/virtualizer.c | 55 ++++++++++++++++++++++++++----------- daemon/virtualizer.h | 4 +++ 18 files changed, 244 insertions(+), 92 deletions(-) diff --git a/daemon/app_supervisor.c b/daemon/app_supervisor.c index ace901b1..62400f40 100644 --- a/daemon/app_supervisor.c +++ b/daemon/app_supervisor.c @@ -38,6 +38,7 @@ struct ladish_app { struct list_head siblings; uint64_t id; + uuid_t uuid; char * name; char * commandline; bool terminal; @@ -174,7 +175,7 @@ const char * ladish_app_supervisor_get_opath(ladish_app_supervisor_handle superv return supervisor_ptr->opath; } -bool ladish_app_supervisor_check_app_name(ladish_app_supervisor_handle supervisor_handle, const char * name) +ladish_app_handle ladish_app_supervisor_find_app_by_name(ladish_app_supervisor_handle supervisor_handle, const char * name) { struct list_head * node_ptr; struct ladish_app * app_ptr; @@ -184,11 +185,11 @@ bool ladish_app_supervisor_check_app_name(ladish_app_supervisor_handle superviso app_ptr = list_entry(node_ptr, struct ladish_app, siblings); if (strcmp(app_ptr->name, name) == 0) { - return true; + return (ladish_app_handle)app_ptr; } } - return false; + return NULL; } ladish_app_handle ladish_app_supervisor_find_app_by_id(ladish_app_supervisor_handle supervisor_handle, uint64_t id) @@ -196,6 +197,24 @@ ladish_app_handle ladish_app_supervisor_find_app_by_id(ladish_app_supervisor_han return (ladish_app_handle)ladish_app_supervisor_find_app_by_id_internal(supervisor_ptr, id); } +ladish_app_handle ladish_app_supervisor_find_app_by_pid(ladish_app_supervisor_handle supervisor_handle, pid_t pid) +{ + struct list_head * node_ptr; + struct ladish_app * app_ptr; + + list_for_each(node_ptr, &supervisor_ptr->applist) + { + app_ptr = list_entry(node_ptr, struct ladish_app, siblings); + if (app_ptr->pid == pid) + { + //log_info("app \"%s\" found by pid %llu", app_ptr->name, (unsigned long long)pid); + return (ladish_app_handle)app_ptr; + } + } + + return NULL; +} + ladish_app_handle ladish_app_supervisor_add( ladish_app_supervisor_handle supervisor_handle, @@ -237,6 +256,7 @@ ladish_app_supervisor_add( app_ptr->pid = 0; app_ptr->id = supervisor_ptr->next_id++; + uuid_generate(app_ptr->uuid); app_ptr->zombie = false; app_ptr->state = LADISH_APP_STATE_STOPPED; app_ptr->autorun = autorun; @@ -372,7 +392,7 @@ bool ladish_app_supervisor_enum( ladish_app_supervisor_handle supervisor_handle, void * context, - bool (* callback)(void * context, const char * name, bool running, const char * command, bool terminal, uint8_t level, pid_t pid)) + ladish_app_supervisor_enum_callback callback) { struct list_head * node_ptr; struct ladish_app * app_ptr; @@ -381,7 +401,7 @@ ladish_app_supervisor_enum( { app_ptr = list_entry(node_ptr, struct ladish_app, siblings); - if (!callback(context, app_ptr->name, app_ptr->pid != 0, app_ptr->commandline, app_ptr->terminal, app_ptr->level, app_ptr->pid)) + if (!callback(context, app_ptr->name, app_ptr->pid != 0, app_ptr->commandline, app_ptr->terminal, app_ptr->level, app_ptr->pid, app_ptr->uuid)) { return false; } @@ -436,6 +456,11 @@ const char * ladish_app_get_name(ladish_app_handle app_handle) return app_ptr->name; } +void ladish_app_get_uuid(ladish_app_handle app_handle, uuid_t uuid) +{ + uuid_copy(uuid, app_ptr->uuid); +} + void ladish_app_stop(ladish_app_handle app_handle) { ladish_app_send_signal(app_ptr, SIGTERM); @@ -530,31 +555,6 @@ void ladish_app_supervisor_save_L1(ladish_app_supervisor_handle supervisor_handl } } -char * ladish_app_supervisor_search_app(ladish_app_supervisor_handle supervisor_handle, pid_t pid) -{ - struct list_head * node_ptr; - struct ladish_app * app_ptr; - char * name; - - list_for_each(node_ptr, &supervisor_ptr->applist) - { - app_ptr = list_entry(node_ptr, struct ladish_app, siblings); - if (app_ptr->pid == pid) - { - //log_info("app \"%s\" found by pid %llu", app_ptr->name, (unsigned long long)pid); - name = strdup(app_ptr->name); - if (name == NULL) - { - log_error("strdup() failed for '%s'", app_ptr->name); - } - - return name; - } - } - - return NULL; -} - const char * ladish_app_supervisor_get_name(ladish_app_supervisor_handle supervisor_handle) { return supervisor_ptr->name; diff --git a/daemon/app_supervisor.h b/daemon/app_supervisor.h index a4e08ebb..b9972503 100644 --- a/daemon/app_supervisor.h +++ b/daemon/app_supervisor.h @@ -69,6 +69,7 @@ typedef void (* ladish_app_supervisor_on_app_renamed_callback)( * @param[in] terminal Whether the app is started in terminal * @param[in] level The level that app was started in * @param[in] pid PID of the app; Zero if app is not started + * @param[in] uuid uuid of the app */ typedef bool (* ladish_app_supervisor_enum_callback)( void * context, @@ -77,7 +78,8 @@ typedef bool (* ladish_app_supervisor_enum_callback)( const char * command, bool terminal, uint8_t level, - pid_t pid); + pid_t pid, + const uuid_t uuid); /** * Create app supervisor object @@ -205,22 +207,6 @@ ladish_app_supervisor_autorun( ladish_app_supervisor_handle supervisor_handle); /** - * Search app by pid and return its name - * - * TODO: this should be renamed to match the fact that it returns app name and not app handle. - * Implementing ladish_app_supervisor_find_app_by_pid() makes sense as well. - * - * @param[in] supervisor_handle supervisor object handle - * @param[in] pid pid of the app to search for - * - * @return app name on success; NULL if app is not found - */ -char * -ladish_app_supervisor_search_app( - ladish_app_supervisor_handle supervisor_handle, - pid_t pid); - -/** * Get name of the supervisor * * TODO: This should be probably removed in favour of ladish_app_supervisor_get_opath(); it is used for debuging purposes only @@ -250,15 +236,14 @@ unsigned int ladish_app_supervisor_get_running_app_count(ladish_app_supervisor_h bool ladish_app_supervisor_has_apps(ladish_app_supervisor_handle supervisor_handle); /** - * Check whether app with name supplied name exists + * Find app by name * * @param[in] supervisor_handle supervisor object handle * @param[in] name name of the app to search for * - * @retval true app with supplied name exists - * @retval false app with supplied name does not exist + * @return app handle on if found; NULL if app is not found; the app handle is owned by the app supervisor object */ -bool ladish_app_supervisor_check_app_name(ladish_app_supervisor_handle supervisor_handle, const char * name); +ladish_app_handle ladish_app_supervisor_find_app_by_name(ladish_app_supervisor_handle supervisor_handle, const char * name); /** * Find app by id (as exposed through the D-Bus interface) @@ -271,6 +256,19 @@ bool ladish_app_supervisor_check_app_name(ladish_app_supervisor_handle superviso ladish_app_handle ladish_app_supervisor_find_app_by_id(ladish_app_supervisor_handle supervisor_handle, uint64_t id); /** + * Search app by process id + * + * @param[in] supervisor_handle supervisor object handle + * @param[in] pid pid of the app to search for + * + * @return app handle on if found; NULL if app is not found; the app handle is owned by the app supervisor object + */ +ladish_app_handle +ladish_app_supervisor_find_app_by_pid( + ladish_app_supervisor_handle supervisor_handle, + pid_t pid); + +/** * The the D-Bus object path for the supervisor. * * @param[in] supervisor_handle supervisor object handle @@ -339,6 +337,15 @@ bool ladish_app_is_running(ladish_app_handle app_handle); const char * ladish_app_get_name(ladish_app_handle app_handle); /** + * Get app uuid + * + * @param[in] app_handle app object handle + * @param[out] uuid pointer to uuid_t storage where the app uuid will be store + * + */ +void ladish_app_get_uuid(ladish_app_handle app_handle, uuid_t uuid); + +/** * Stop an app. The app must be in started state. * * @param[in] app_handle Handle of app to stop diff --git a/daemon/client.c b/daemon/client.c index 05b8113b..60be932a 100644 --- a/daemon/client.c +++ b/daemon/client.c @@ -31,6 +31,7 @@ struct ladish_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_app; /* The UUID of the app that owns this client */ uint64_t jack_id; /* JACK client ID */ pid_t pid; /* process id. */ ladish_dict_handle dict; @@ -68,6 +69,7 @@ ladish_client_create( } uuid_clear(client_ptr->uuid_interlink); + uuid_clear(client_ptr->uuid_app); client_ptr->jack_id = 0; client_ptr->pid = 0; @@ -174,4 +176,25 @@ void ladish_client_clear_interlink(ladish_client_handle client_handle) uuid_clear(client_ptr->uuid_interlink); } +void ladish_client_set_app(ladish_client_handle client_handle, const uuid_t uuid) +{ + uuid_copy(client_ptr->uuid_app, uuid); +} + +bool ladish_client_get_app(ladish_client_handle client_handle, uuid_t uuid) +{ + if (uuid_is_null(client_ptr->uuid_app)) + { + return false; + } + + uuid_copy(uuid, client_ptr->uuid_app); + return true; +} + +bool ladish_client_has_app(ladish_client_handle client_handle) +{ + return !uuid_is_null(client_ptr->uuid_app); +} + #undef client_ptr diff --git a/daemon/client.h b/daemon/client.h index 3e6bd588..e38f3e16 100644 --- a/daemon/client.h +++ b/daemon/client.h @@ -62,4 +62,8 @@ void ladish_client_interlink(ladish_client_handle client1_handle, ladish_client_ bool ladish_client_get_interlink(ladish_client_handle client_handle, uuid_t uuid); void ladish_client_clear_interlink(ladish_client_handle client_handle); +void ladish_client_set_app(ladish_client_handle client_handle, const uuid_t uuid); +bool ladish_client_get_app(ladish_client_handle client_handle, uuid_t uuid); +bool ladish_client_has_app(ladish_client_handle client_handle); + #endif /* #ifndef CLIENT_H__2160B4BA_D6D1_464D_9DC5_ECA50B0958AD__INCLUDED */ diff --git a/daemon/cmd_change_app_state.c b/daemon/cmd_change_app_state.c index 14852f26..e65dd76e 100644 --- a/daemon/cmd_change_app_state.c +++ b/daemon/cmd_change_app_state.c @@ -74,10 +74,12 @@ static bool run_target_start(struct ladish_command_change_app_state * cmd_ptr, l static bool run_target_stop(struct ladish_command_change_app_state * cmd_ptr, ladish_app_supervisor_handle supervisor, ladish_app_handle app) { const char * app_name; + uuid_t app_uuid; ASSERT(cmd_ptr->initiate_stop != NULL); app_name = ladish_app_get_name(app); + ladish_app_get_uuid(app, app_uuid); if (ladish_app_is_running(app)) { @@ -93,7 +95,7 @@ static bool run_target_stop(struct ladish_command_change_app_state * cmd_ptr, la return true; } - if (!ladish_virtualizer_is_hidden_app(ladish_studio_get_jack_graph(), app_name)) + if (!ladish_virtualizer_is_hidden_app(ladish_studio_get_jack_graph(), app_uuid, app_name)) { log_info("Waiting '%s' client disappear (%s)...", app_name, cmd_ptr->target_state_description); return true; diff --git a/daemon/cmd_new_app.c b/daemon/cmd_new_app.c index 4ec851c8..f8506ccb 100644 --- a/daemon/cmd_new_app.c +++ b/daemon/cmd_new_app.c @@ -118,7 +118,7 @@ static bool run(void * context) /* make the app name unique */ index = 2; - while (ladish_app_supervisor_check_app_name(supervisor, name)) + while (ladish_app_supervisor_find_app_by_name(supervisor, name) != NULL) { sprintf(end, "-%u", index); index++; diff --git a/daemon/cmd_remove_app.c b/daemon/cmd_remove_app.c index 533fcbb6..0afaea1b 100644 --- a/daemon/cmd_remove_app.c +++ b/daemon/cmd_remove_app.c @@ -45,6 +45,7 @@ static bool run(void * context) ladish_app_supervisor_handle supervisor; ladish_app_handle app; const char * app_name; + uuid_t app_uuid; ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING); @@ -67,6 +68,7 @@ static bool run(void * context) } app_name = ladish_app_get_name(app); + ladish_app_get_uuid(app, app_uuid); if (ladish_app_is_running(app)) { @@ -80,7 +82,7 @@ static bool run(void * context) /* remove jclient and vclient for this app */ log_info("Removing graph objects for app '%s'", app_name); - ladish_virtualizer_remove_app(ladish_studio_get_jack_graph(), app_name); + ladish_virtualizer_remove_app(ladish_studio_get_jack_graph(), app_uuid, app_name); ladish_app_supervisor_remove_app(supervisor, app); cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; diff --git a/daemon/graph.c b/daemon/graph.c index af872ca9..52f8c23a 100644 --- a/daemon/graph.c +++ b/daemon/graph.c @@ -1586,7 +1586,7 @@ ladish_graph_find_connection( return true; } -ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_handle, const char * name) +ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_handle, const char * name, bool appless) { struct list_head * node_ptr; struct ladish_graph_client * client_ptr; @@ -1594,7 +1594,27 @@ ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_ list_for_each(node_ptr, &graph_ptr->clients) { client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings); - 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 */ + { + return client_ptr->client; + } + } + + return NULL; +} + +ladish_client_handle ladish_graph_find_client_by_app(ladish_graph_handle graph_handle, const uuid_t app_uuid) +{ + struct list_head * node_ptr; + struct ladish_graph_client * client_ptr; + uuid_t current_uuid; + + list_for_each(node_ptr, &graph_ptr->clients) + { + client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings); + ladish_client_get_app(client_ptr->client, current_uuid); + if (uuid_compare(current_uuid, app_uuid) == 0) { return client_ptr->client; } @@ -1957,6 +1977,16 @@ void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle) list_for_each(node_ptr, &graph_ptr->connections) { connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings); + log_debug( + "checking connection (%s, %s) '%s':'%s' (%s) to '%s':'%s' (%s)", + connection_ptr->hidden ? "hidden" : "visible", + connection_ptr->changing ? "changing" : "not changing", + connection_ptr->port1_ptr->client_ptr->name, + connection_ptr->port1_ptr->name, + connection_ptr->port1_ptr->hidden ? "hidden" : "visible", + connection_ptr->port2_ptr->client_ptr->name, + connection_ptr->port2_ptr->name, + connection_ptr->port2_ptr->hidden ? "hidden" : "visible"); if (connection_ptr->hidden && !connection_ptr->changing && !connection_ptr->port1_ptr->hidden && diff --git a/daemon/graph.h b/daemon/graph.h index 71db41b9..cc2f3552 100644 --- a/daemon/graph.h +++ b/daemon/graph.h @@ -139,7 +139,8 @@ ladish_client_handle ladish_graph_find_client_by_id(ladish_graph_handle graph_ha ladish_port_handle ladish_graph_find_port_by_id(ladish_graph_handle graph_handle, uint64_t port_id); ladish_client_handle ladish_graph_find_client_by_jack_id(ladish_graph_handle graph_handle, uint64_t client_id); ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_handle, uint64_t port_id, bool room, bool studio); -ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_handle, const char * name); +ladish_client_handle ladish_graph_find_client_by_name(ladish_graph_handle graph_handle, const char * name, bool appless); +ladish_client_handle ladish_graph_find_client_by_app(ladish_graph_handle graph_handle, const uuid_t app_uuid); ladish_port_handle ladish_graph_find_port_by_name(ladish_graph_handle graph_handle, ladish_client_handle client_handle, const char * name); ladish_client_handle ladish_graph_find_client_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid); ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, bool use_link_override_uuids); diff --git a/daemon/load.c b/daemon/load.c index a73df5f2..1dd71e7e 100644 --- a/daemon/load.c +++ b/daemon/load.c @@ -274,6 +274,14 @@ ladish_parse_port_type_and_direction_attributes( return true; } +struct interlink_context +{ + ladish_graph_handle vgraph; + ladish_app_supervisor_handle app_supervisor; +}; + +#define ctx_ptr ((struct interlink_context *)context) + static bool interlink_client( @@ -283,39 +291,70 @@ interlink_client( const char * name, void ** client_iteration_context_ptr_ptr) { - uuid_t uuid; + uuid_t app_uuid; + uuid_t vclient_uuid; ladish_client_handle vclient; pid_t pid; + ladish_app_handle app; + bool interlinked; + bool jmcore; if (strcmp(name, "system") == 0) { return true; } - if (ladish_client_get_interlink(jclient, uuid)) + interlinked = ladish_client_get_interlink(jclient, vclient_uuid); + + if (ladish_client_has_app(jclient)) + { + ASSERT(interlinked); /* jclient has app associated but is not interlinked */ + return true; + } + else if (interlinked) + { + ASSERT_NO_PASS; /* jclient has no app associated but is interlinked */ + return true; + } + ASSERT(!interlinked); + + pid = ladish_client_get_pid(jclient); + jmcore = pid != 0 && pid != jmcore_proxy_get_pid_cached(); + if (jmcore) { - ASSERT_NO_PASS; /* interlinks are not stored in xml yet */ return true; } - vclient = ladish_graph_find_client_by_name(context, name); + app = ladish_app_supervisor_find_app_by_name(ctx_ptr->app_supervisor, name); + if (app == NULL) + { + log_info("JACK client \"%s\" not found in app supervisor", name); + return true; + } + + vclient = ladish_graph_find_client_by_name(ctx_ptr->vgraph, name, true); if (vclient == NULL) { - /* jmcore clients are running when projects are being loaded */ - pid = ladish_client_get_pid(jclient); - if (pid != jmcore_proxy_get_pid_cached()) - { - log_error("JACK client '%s' has no vclient associated", name); - } + log_error("JACK client '%s' has no vclient associated", name); return true; } log_info("Interlinking clients of app '%s'", name); ladish_client_interlink(jclient, vclient); + + ladish_app_get_uuid(app, app_uuid); + ladish_client_set_app(jclient, app_uuid); + ladish_client_set_app(vclient, app_uuid); + return true; } -void ladish_interlink_clients(ladish_graph_handle vgraph) +void ladish_interlink_clients(ladish_graph_handle vgraph, ladish_app_supervisor_handle app_supervisor) { - ladish_graph_iterate_nodes(ladish_studio_get_jack_graph(), false, NULL, vgraph, interlink_client, NULL, NULL); + struct interlink_context ctx; + + ctx.vgraph = vgraph; + ctx.app_supervisor = app_supervisor; + + ladish_graph_iterate_nodes(ladish_studio_get_jack_graph(), false, NULL, &ctx, interlink_client, NULL, NULL); } diff --git a/daemon/load.h b/daemon/load.h index 9771c5b8..b905d036 100644 --- a/daemon/load.h +++ b/daemon/load.h @@ -94,6 +94,6 @@ ladish_parse_port_type_and_direction_attributes( uint32_t * type_ptr, uint32_t * flags_ptr); -void ladish_interlink_clients(ladish_graph_handle vgraph); +void ladish_interlink_clients(ladish_graph_handle vgraph, ladish_app_supervisor_handle app_supervisor); #endif /* #ifndef LOAD_H__43B1ECB8_247F_4868_AE95_563DD968D7B0__INCLUDED */ diff --git a/daemon/room.c b/daemon/room.c index 8d704f8e..e1793fbd 100644 --- a/daemon/room.c +++ b/daemon/room.c @@ -617,7 +617,8 @@ ladish_room_app_is_stopped( const char * command, bool terminal, uint8_t level, - pid_t pid) + pid_t pid, + const uuid_t uuid) { if (pid != 0) { @@ -625,7 +626,7 @@ ladish_room_app_is_stopped( return false; } - if (!ladish_virtualizer_is_hidden_app(ladish_studio_get_jack_graph(), name)) + if (!ladish_virtualizer_is_hidden_app(ladish_studio_get_jack_graph(), uuid, name)) { log_info("App '%s' is still visible in the jack graph", name); return false; diff --git a/daemon/room_load.c b/daemon/room_load.c index 55117630..331b2a1e 100644 --- a/daemon/room_load.c +++ b/daemon/room_load.c @@ -729,7 +729,7 @@ bool ladish_room_load_project(ladish_room_handle room_handle, const char * proje goto free_parser; } - ladish_interlink_clients(room_ptr->graph); + ladish_interlink_clients(room_ptr->graph, room_ptr->app_supervisor); /* ladish_graph_dump(ladish_studio_get_jack_graph()); */ /* ladish_graph_dump(room_ptr->graph); */ diff --git a/daemon/save.c b/daemon/save.c index c6ede386..a3f73c14 100644 --- a/daemon/save.c +++ b/daemon/save.c @@ -375,7 +375,17 @@ ladish_save_vgraph_connection( return true; } -static bool ladish_save_app(void * context, const char * name, bool running, const char * command, bool terminal, uint8_t level, pid_t pid) +static +bool +ladish_save_app( + void * context, + const char * name, + bool running, + const char * command, + bool terminal, + uint8_t level, + pid_t pid, + const uuid_t uuid) { char buf[100]; const char * unescaped_string; diff --git a/daemon/studio.c b/daemon/studio.c index 7ff6308c..0c8bb8c3 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -513,13 +513,13 @@ void ladish_on_app_renamed(void * context, const char * old_name, const char * n { ladish_client_handle client; - client = ladish_graph_find_client_by_name(g_studio.jack_graph, old_name); + client = ladish_graph_find_client_by_name(g_studio.jack_graph, old_name, false); if (client != NULL) { ladish_graph_rename_client(g_studio.jack_graph, client, new_app_name); } - client = ladish_graph_find_client_by_name(context, old_name); + client = ladish_graph_find_client_by_name(context, old_name, false); if (client != NULL) { ladish_graph_rename_client(context, client, new_app_name); @@ -741,6 +741,11 @@ ladish_graph_handle ladish_studio_get_studio_graph(void) return g_studio.studio_graph; } +ladish_app_supervisor_handle ladish_studio_get_studio_app_supervisor(void) +{ + return g_studio.app_supervisor; +} + struct ladish_studio_app_supervisor_match_context { const char * opath; diff --git a/daemon/studio.h b/daemon/studio.h index 4cf55da9..621bd27e 100644 --- a/daemon/studio.h +++ b/daemon/studio.h @@ -64,6 +64,7 @@ struct ladish_cqueue * ladish_studio_get_cmd_queue(void); ladish_virtualizer_handle ladish_studio_get_virtualizer(void); ladish_graph_handle ladish_studio_get_jack_graph(void); ladish_graph_handle ladish_studio_get_studio_graph(void); +ladish_app_supervisor_handle ladish_studio_get_studio_app_supervisor(void); bool ladish_studio_has_rooms(void); unsigned int ladish_studio_get_room_index(void); diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index ab09370b..8e54ee4a 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -56,15 +56,16 @@ struct app_find_context { pid_t pid; char * app_name; + uuid_t app_uuid; ladish_graph_handle graph; }; #define app_find_context_ptr ((struct app_find_context *)context) -bool get_app_name_from_supervisor(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) +static bool get_app_properties_from_supervisor(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) { pid_t pid; - char * app_name; + ladish_app_handle app; ASSERT(app_find_context_ptr->app_name == NULL); /* we stop iteration when app is found */ @@ -73,8 +74,8 @@ bool get_app_name_from_supervisor(void * context, ladish_graph_handle graph, lad pid = app_find_context_ptr->pid; do { - app_name = ladish_app_supervisor_search_app(app_supervisor, pid); - if (app_name != NULL) + app = ladish_app_supervisor_find_app_by_pid(app_supervisor, pid); + if (app != NULL) break; pid = (pid_t)procfs_get_process_parent((unsigned long long)pid); @@ -87,33 +88,45 @@ bool get_app_name_from_supervisor(void * context, ladish_graph_handle graph, lad } while (pid != 0); - if (app_name != NULL) + if (app == NULL) + { /* app not found in current supervisor */ + return true; /* continue app supervisor iteration */ + } + + app_find_context_ptr->app_name = strdup(ladish_app_get_name(app)); + if (app_find_context_ptr->app_name == NULL) + { + log_error("strdup() failed for app name '%s'", ladish_app_get_name(app)); + } + else { - app_find_context_ptr->app_name = app_name; + ladish_app_get_uuid(app, app_find_context_ptr->app_uuid); app_find_context_ptr->pid = pid; app_find_context_ptr->graph = graph; - return false; /* stop app supervisor iteration */ } - return true; /* continue app supervisor iteration */ + return false; /* stop app supervisor iteration */ } #undef app_find_context_ptr -char * get_app_name(struct virtualizer * virtualizer_ptr, uint64_t client_id, pid_t pid, ladish_graph_handle * graph_ptr) +static char * get_app_properties(struct virtualizer * virtualizer_ptr, uint64_t client_id, pid_t pid, ladish_graph_handle * graph_ptr, uuid_t app_uuid) { struct app_find_context context; context.pid = (pid_t)pid; context.app_name = NULL; context.graph = NULL; + uuid_clear(context.app_uuid); - ladish_studio_iterate_virtual_graphs(&context, get_app_name_from_supervisor); + ladish_studio_iterate_virtual_graphs(&context, get_app_properties_from_supervisor); if (context.app_name != NULL) { ASSERT(context.graph != NULL); + ASSERT(!uuid_is_null(context.app_uuid)); *graph_ptr = context.graph; + uuid_copy(app_uuid, context.app_uuid); } return context.app_name; @@ -259,6 +272,7 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name) const char * a2j_name; bool is_a2j; char * app_name; + uuid_t app_uuid; const char * name; pid_t pid; ladish_graph_handle graph; @@ -271,6 +285,7 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name) name = jack_name; app_name = NULL; + graph = NULL; jmcore = false; if (!graph_proxy_get_client_pid(virtualizer_ptr->jack_graph_proxy, id, &pid)) @@ -290,7 +305,7 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name) } else { - app_name = get_app_name(virtualizer_ptr, id, pid, &graph); + app_name = get_app_properties(virtualizer_ptr, id, pid, &graph, app_uuid); if (app_name != NULL) { log_info("app name is '%s'", app_name); @@ -308,7 +323,12 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name) } else { - client = ladish_graph_find_client_by_name(virtualizer_ptr->jack_graph, name); + client = ladish_graph_find_client_by_app(virtualizer_ptr->jack_graph, app_uuid); + if (client == NULL) + { + log_info("Lookup by app uuid failed, attempting lookup by name '%s'", name); + client = ladish_graph_find_client_by_name(virtualizer_ptr->jack_graph, name, true); + } } if (client != NULL) @@ -350,6 +370,8 @@ done: if (app_name != NULL) { ladish_client_set_pid(client, pid); + ladish_client_set_app(client, app_uuid); + ASSERT(graph); ladish_client_set_vgraph(client, graph); virtualizer_ptr->our_clients_count++; } @@ -605,7 +627,7 @@ port_appeared( if (is_a2j) { - vclient = ladish_graph_find_client_by_name(vgraph, alsa_client_name); + vclient = ladish_graph_find_client_by_name(vgraph, alsa_client_name, false); if (vclient == NULL) { if (!ladish_client_create(NULL, &vclient)) @@ -621,7 +643,6 @@ port_appeared( goto free_alsa_names; } } - } else if (client_id == virtualizer_ptr->system_client_id) { @@ -1052,6 +1073,7 @@ ladish_virtualizer_get_our_clients_count( bool ladish_virtualizer_is_hidden_app( ladish_graph_handle jack_graph, + const uuid_t app_uuid, const char * app_name) { ladish_client_handle jclient; @@ -1064,7 +1086,7 @@ ladish_virtualizer_is_hidden_app( //ladish_graph_dump(g_studio.jack_graph); - jclient = ladish_graph_find_client_by_name(jack_graph, app_name); + jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid); if (jclient == NULL) { log_info("App without JACK client is treated as hidden one"); @@ -1129,6 +1151,7 @@ ladish_virtualizer_is_hidden_app( void ladish_virtualizer_remove_app( ladish_graph_handle jack_graph, + const uuid_t app_uuid, const char * app_name) { ladish_client_handle jclient; @@ -1141,7 +1164,7 @@ ladish_virtualizer_remove_app( //ladish_graph_dump(g_studio.jack_graph); - jclient = ladish_graph_find_client_by_name(jack_graph, app_name); + jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid); if (jclient == NULL) { log_info("removing app without JACK client"); diff --git a/daemon/virtualizer.h b/daemon/virtualizer.h index c605c231..9389ba5a 100644 --- a/daemon/virtualizer.h +++ b/daemon/virtualizer.h @@ -51,13 +51,17 @@ ladish_virtualizer_get_our_clients_count( bool ladish_virtualizer_is_hidden_app( ladish_graph_handle graph_hanle, + const uuid_t app_uuid, const char * app_name); void ladish_virtualizer_remove_app( ladish_graph_handle graph_hanle, + const uuid_t app_uuid, const char * app_name); +void ladish_virtualizer_rename_app(void * context, const char * old_name, const char * new_app_name); + void ladish_virtualizer_destroy( ladish_virtualizer_handle handle); -- 2.11.4.GIT