From e8f9b6b02ee1b13c36af920f47f12b3c129cd498 Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Tue, 30 Nov 2010 00:13:11 +0200 Subject: [PATCH] ladishd: Deassociate pids of disappearing clients. Fix for #119 --- daemon/app_supervisor.c | 26 ++++++++++++++++++++++++ daemon/app_supervisor.h | 21 ++++++++++++++++++++ daemon/studio.c | 44 ++++++++++++++++++++++++++++++++++++----- daemon/studio.h | 1 + daemon/virtualizer.c | 14 ++++++++++++- 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/daemon/app_supervisor.c b/daemon/app_supervisor.c index f1f50129..ccee4f40 100644 --- a/daemon/app_supervisor.c +++ b/daemon/app_supervisor.c @@ -225,6 +225,23 @@ ladish_app_handle ladish_app_supervisor_find_app_by_pid(ladish_app_supervisor_ha return NULL; } +ladish_app_handle ladish_app_supervisor_find_app_by_uuid(ladish_app_supervisor_handle supervisor_handle, const uuid_t uuid) +{ + 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 (uuid_compare(app_ptr->uuid, uuid) == 0) + { + return (ladish_app_handle)app_ptr; + } + } + + return NULL; +} + ladish_app_handle ladish_app_supervisor_add( ladish_app_supervisor_handle supervisor_handle, @@ -598,6 +615,15 @@ void ladish_app_add_pid(ladish_app_handle app_handle, pid_t pid) app_ptr->firstborn_pid = pid; } +void ladish_app_del_pid(ladish_app_handle app_handle, pid_t pid) +{ + if (app_ptr->firstborn_pid != 0 && app_ptr->firstborn_pid == pid) + { + log_info("First grandchild with pid %u has gone", (unsigned int)pid); + app_ptr->firstborn_pid = 0; + } +} + #undef app_ptr void ladish_app_supervisor_autorun(ladish_app_supervisor_handle supervisor_handle) diff --git a/daemon/app_supervisor.h b/daemon/app_supervisor.h index 1cae5e04..e081f7da 100644 --- a/daemon/app_supervisor.h +++ b/daemon/app_supervisor.h @@ -286,6 +286,19 @@ ladish_app_supervisor_find_app_by_pid( ladish_app_supervisor_handle supervisor_handle, pid_t pid); +/** + * Search app by uuid + * + * @param[in] supervisor_handle supervisor object handle + * @param[in] uuid uuid 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_uuid( + ladish_app_supervisor_handle supervisor_handle, + const uuid_t uuid); + /** * The the D-Bus object path for the supervisor. * @@ -392,6 +405,14 @@ void ladish_app_save_L1(ladish_app_handle app_handle); */ void ladish_app_add_pid(ladish_app_handle app_handle, pid_t pid); +/** + * Deassociate pid with app. + * + * @param[in] app_handle Handle of app + * @param[in] pid PID to deassociate with the app + */ +void ladish_app_del_pid(ladish_app_handle app_handle, pid_t pid); + /** * D-Bus interface descriptor for the app supervisor interface. The call context must be a ::ladish_app_supervisor_handle */ diff --git a/daemon/studio.c b/daemon/studio.c index 9e9e7e9b..2cfe98aa 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -773,15 +773,15 @@ ladish_app_supervisor_handle ladish_studio_get_studio_app_supervisor(void) return g_studio.app_supervisor; } -struct ladish_studio_app_supervisor_match_context +struct ladish_studio_app_supervisor_match_opath_context { const char * opath; ladish_app_supervisor_handle supervisor; }; -#define iterate_context_ptr ((struct ladish_studio_app_supervisor_match_context *)context) +#define iterate_context_ptr ((struct ladish_studio_app_supervisor_match_opath_context *)context) -static bool ladish_studio_app_supervisor_match(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) +static bool ladish_studio_app_supervisor_match_opath(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) { ASSERT(strcmp(ladish_app_supervisor_get_opath(app_supervisor), ladish_graph_get_opath(graph)) == 0); if (strcmp(ladish_app_supervisor_get_opath(app_supervisor), iterate_context_ptr->opath) == 0) @@ -798,14 +798,48 @@ static bool ladish_studio_app_supervisor_match(void * context, ladish_graph_hand ladish_app_supervisor_handle ladish_studio_find_app_supervisor(const char * opath) { - struct ladish_studio_app_supervisor_match_context ctx; + struct ladish_studio_app_supervisor_match_opath_context ctx; ctx.opath = opath; ctx.supervisor = NULL; - ladish_studio_iterate_virtual_graphs(&ctx, ladish_studio_app_supervisor_match); + ladish_studio_iterate_virtual_graphs(&ctx, ladish_studio_app_supervisor_match_opath); return ctx.supervisor; } +struct ladish_studio_app_supervisor_match_app_context +{ + uuid_t app_uuid; + ladish_app_handle app; +}; + +#define iterate_context_ptr ((struct ladish_studio_app_supervisor_match_app_context *)context) + +static bool ladish_studio_app_supervisor_match_app(void * context, ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) +{ + ASSERT(strcmp(ladish_app_supervisor_get_opath(app_supervisor), ladish_graph_get_opath(graph)) == 0); + ASSERT(iterate_context_ptr->app == NULL); + + iterate_context_ptr->app = ladish_app_supervisor_find_app_by_uuid(app_supervisor, iterate_context_ptr->app_uuid); + if (iterate_context_ptr->app != NULL) + { + return false; /* stop iteration */ + } + + return true; /* continue iteration */ +} + +#undef iterate_context_ptr + +ladish_app_handle ladish_studio_find_app_by_uuid(const uuid_t app_uuid) +{ + struct ladish_studio_app_supervisor_match_app_context ctx; + + uuid_copy(ctx.app_uuid, app_uuid); + ctx.app = NULL; + ladish_studio_iterate_virtual_graphs(&ctx, ladish_studio_app_supervisor_match_app); + return ctx.app; +} + bool ladish_studio_delete(void * call_ptr, const char * studio_name) { char * filename; diff --git a/daemon/studio.h b/daemon/studio.h index 47dc0645..11a01d3c 100644 --- a/daemon/studio.h +++ b/daemon/studio.h @@ -60,6 +60,7 @@ ladish_studio_iterate_rooms( void ladish_studio_stop_app_supervisors(void); ladish_app_supervisor_handle ladish_studio_find_app_supervisor(const char * opath); +ladish_app_handle ladish_studio_find_app_by_uuid(const uuid_t app_uuid); 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); diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index 33f9938a..67da3971 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -383,6 +383,8 @@ static void client_disappeared(void * context, uint64_t id) { ladish_client_handle client; pid_t pid; + uuid_t app_uuid; + ladish_app_handle app; ladish_graph_handle vgraph; log_info("client_disappeared(%"PRIu64")", id); @@ -399,9 +401,19 @@ static void client_disappeared(void * context, uint64_t id) vgraph = ladish_client_get_vgraph(client); pid = ladish_client_get_pid(client); - if (ladish_client_has_app(client)) + if (ladish_client_get_app(client, app_uuid)) { virtualizer_ptr->our_clients_count--; + app = ladish_studio_find_app_by_uuid(app_uuid); + if (app != NULL) + { + ladish_app_del_pid(app, pid); + } + else + { + log_error("app of disappearing client %"PRIu64" not found. pid is %"PRIu64, id, (uint64_t)pid); + ASSERT_NO_PASS; + } } if (id == virtualizer_ptr->system_client_id)