daemon: handle apps with same name in different vgraphs

This commit is contained in:
Nedko Arnaudov 2010-08-30 00:05:57 +03:00
parent 1f4af5f439
commit 76a8b6161b
18 changed files with 247 additions and 95 deletions

View File

@ -38,6 +38,7 @@ struct ladish_app
{ {
struct list_head siblings; struct list_head siblings;
uint64_t id; uint64_t id;
uuid_t uuid;
char * name; char * name;
char * commandline; char * commandline;
bool terminal; bool terminal;
@ -174,7 +175,7 @@ const char * ladish_app_supervisor_get_opath(ladish_app_supervisor_handle superv
return supervisor_ptr->opath; 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 list_head * node_ptr;
struct ladish_app * app_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); app_ptr = list_entry(node_ptr, struct ladish_app, siblings);
if (strcmp(app_ptr->name, name) == 0) 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) 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); 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_handle
ladish_app_supervisor_add( ladish_app_supervisor_add(
ladish_app_supervisor_handle supervisor_handle, ladish_app_supervisor_handle supervisor_handle,
@ -237,6 +256,7 @@ ladish_app_supervisor_add(
app_ptr->pid = 0; app_ptr->pid = 0;
app_ptr->id = supervisor_ptr->next_id++; app_ptr->id = supervisor_ptr->next_id++;
uuid_generate(app_ptr->uuid);
app_ptr->zombie = false; app_ptr->zombie = false;
app_ptr->state = LADISH_APP_STATE_STOPPED; app_ptr->state = LADISH_APP_STATE_STOPPED;
app_ptr->autorun = autorun; app_ptr->autorun = autorun;
@ -372,7 +392,7 @@ bool
ladish_app_supervisor_enum( ladish_app_supervisor_enum(
ladish_app_supervisor_handle supervisor_handle, ladish_app_supervisor_handle supervisor_handle,
void * context, 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 list_head * node_ptr;
struct ladish_app * app_ptr; struct ladish_app * app_ptr;
@ -381,7 +401,7 @@ ladish_app_supervisor_enum(
{ {
app_ptr = list_entry(node_ptr, struct ladish_app, siblings); 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; return false;
} }
@ -436,6 +456,11 @@ const char * ladish_app_get_name(ladish_app_handle app_handle)
return app_ptr->name; 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) void ladish_app_stop(ladish_app_handle app_handle)
{ {
ladish_app_send_signal(app_ptr, SIGTERM); 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) const char * ladish_app_supervisor_get_name(ladish_app_supervisor_handle supervisor_handle)
{ {
return supervisor_ptr->name; return supervisor_ptr->name;

View File

@ -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] terminal Whether the app is started in terminal
* @param[in] level The level that app was started in * @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] 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)( typedef bool (* ladish_app_supervisor_enum_callback)(
void * context, void * context,
@ -77,7 +78,8 @@ typedef bool (* ladish_app_supervisor_enum_callback)(
const char * command, const char * command,
bool terminal, bool terminal,
uint8_t level, uint8_t level,
pid_t pid); pid_t pid,
const uuid_t uuid);
/** /**
* Create app supervisor object * Create app supervisor object
@ -204,22 +206,6 @@ void
ladish_app_supervisor_autorun( ladish_app_supervisor_autorun(
ladish_app_supervisor_handle supervisor_handle); 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 * Get name of the supervisor
* *
@ -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); 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] supervisor_handle supervisor object handle
* @param[in] name name of the app to search for * @param[in] name name of the app to search for
* *
* @retval true app with supplied name exists * @return app handle on if found; NULL if app is not found; the app handle is owned by the app supervisor object
* @retval false app with supplied name does not exist
*/ */
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) * Find app by id (as exposed through the D-Bus interface)
@ -270,6 +255,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); 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. * The the D-Bus object path for the supervisor.
* *
@ -338,6 +336,15 @@ bool ladish_app_is_running(ladish_app_handle app_handle);
*/ */
const char * ladish_app_get_name(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. * Stop an app. The app must be in started state.
* *

View File

@ -31,6 +31,7 @@ struct ladish_client
{ {
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 */
uint64_t jack_id; /* JACK client ID */ uint64_t jack_id; /* JACK client ID */
pid_t pid; /* process id. */ pid_t pid; /* process id. */
ladish_dict_handle dict; ladish_dict_handle dict;
@ -68,6 +69,7 @@ ladish_client_create(
} }
uuid_clear(client_ptr->uuid_interlink); uuid_clear(client_ptr->uuid_interlink);
uuid_clear(client_ptr->uuid_app);
client_ptr->jack_id = 0; client_ptr->jack_id = 0;
client_ptr->pid = 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); 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 #undef client_ptr

View File

@ -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); 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_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 */ #endif /* #ifndef CLIENT_H__2160B4BA_D6D1_464D_9DC5_ECA50B0958AD__INCLUDED */

View File

@ -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) 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; const char * app_name;
uuid_t app_uuid;
ASSERT(cmd_ptr->initiate_stop != NULL); ASSERT(cmd_ptr->initiate_stop != NULL);
app_name = ladish_app_get_name(app); app_name = ladish_app_get_name(app);
ladish_app_get_uuid(app, app_uuid);
if (ladish_app_is_running(app)) 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; 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); log_info("Waiting '%s' client disappear (%s)...", app_name, cmd_ptr->target_state_description);
return true; return true;

View File

@ -118,7 +118,7 @@ static bool run(void * context)
/* make the app name unique */ /* make the app name unique */
index = 2; 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); sprintf(end, "-%u", index);
index++; index++;

View File

@ -45,6 +45,7 @@ static bool run(void * context)
ladish_app_supervisor_handle supervisor; ladish_app_supervisor_handle supervisor;
ladish_app_handle app; ladish_app_handle app;
const char * app_name; const char * app_name;
uuid_t app_uuid;
ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING); 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); app_name = ladish_app_get_name(app);
ladish_app_get_uuid(app, app_uuid);
if (ladish_app_is_running(app)) if (ladish_app_is_running(app))
{ {
@ -80,7 +82,7 @@ static bool run(void * context)
/* remove jclient and vclient for this app */ /* remove jclient and vclient for this app */
log_info("Removing graph objects for app '%s'", app_name); 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); ladish_app_supervisor_remove_app(supervisor, app);
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE; cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;

View File

@ -1586,7 +1586,7 @@ ladish_graph_find_connection(
return true; 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 list_head * node_ptr;
struct ladish_graph_client * client_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) list_for_each(node_ptr, &graph_ptr->clients)
{ {
client_ptr = list_entry(node_ptr, struct ladish_graph_client, siblings); 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; 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) list_for_each(node_ptr, &graph_ptr->connections)
{ {
connection_ptr = list_entry(node_ptr, struct ladish_graph_connection, siblings); 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 && if (connection_ptr->hidden &&
!connection_ptr->changing && !connection_ptr->changing &&
!connection_ptr->port1_ptr->hidden && !connection_ptr->port1_ptr->hidden &&

View File

@ -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_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_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_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_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_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); ladish_port_handle ladish_graph_find_port_by_uuid(ladish_graph_handle graph_handle, const uuid_t uuid, bool use_link_override_uuids);

View File

@ -274,6 +274,14 @@ ladish_parse_port_type_and_direction_attributes(
return true; return true;
} }
struct interlink_context
{
ladish_graph_handle vgraph;
ladish_app_supervisor_handle app_supervisor;
};
#define ctx_ptr ((struct interlink_context *)context)
static static
bool bool
interlink_client( interlink_client(
@ -283,39 +291,70 @@ interlink_client(
const char * name, const char * name,
void ** client_iteration_context_ptr_ptr) void ** client_iteration_context_ptr_ptr)
{ {
uuid_t uuid; uuid_t app_uuid;
uuid_t vclient_uuid;
ladish_client_handle vclient; ladish_client_handle vclient;
pid_t pid; pid_t pid;
ladish_app_handle app;
bool interlinked;
bool jmcore;
if (strcmp(name, "system") == 0) if (strcmp(name, "system") == 0)
{ {
return true; 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; 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) 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; return true;
} }
log_info("Interlinking clients of app '%s'", name); log_info("Interlinking clients of app '%s'", name);
ladish_client_interlink(jclient, vclient); 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; 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);
} }

View File

@ -94,6 +94,6 @@ ladish_parse_port_type_and_direction_attributes(
uint32_t * type_ptr, uint32_t * type_ptr,
uint32_t * flags_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 */ #endif /* #ifndef LOAD_H__43B1ECB8_247F_4868_AE95_563DD968D7B0__INCLUDED */

View File

@ -617,7 +617,8 @@ ladish_room_app_is_stopped(
const char * command, const char * command,
bool terminal, bool terminal,
uint8_t level, uint8_t level,
pid_t pid) pid_t pid,
const uuid_t uuid)
{ {
if (pid != 0) if (pid != 0)
{ {
@ -625,7 +626,7 @@ ladish_room_app_is_stopped(
return false; 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); log_info("App '%s' is still visible in the jack graph", name);
return false; return false;

View File

@ -729,7 +729,7 @@ bool ladish_room_load_project(ladish_room_handle room_handle, const char * proje
goto free_parser; 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(ladish_studio_get_jack_graph()); */
/* ladish_graph_dump(room_ptr->graph); */ /* ladish_graph_dump(room_ptr->graph); */

View File

@ -375,7 +375,17 @@ ladish_save_vgraph_connection(
return true; 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]; char buf[100];
const char * unescaped_string; const char * unescaped_string;

View File

@ -513,13 +513,13 @@ void ladish_on_app_renamed(void * context, const char * old_name, const char * n
{ {
ladish_client_handle client; 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) 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);
} }
client = ladish_graph_find_client_by_name(context, old_name); client = ladish_graph_find_client_by_name(context, old_name, false);
if (client != NULL) if (client != NULL)
{ {
ladish_graph_rename_client(context, client, new_app_name); 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; 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 struct ladish_studio_app_supervisor_match_context
{ {
const char * opath; const char * opath;

View File

@ -64,6 +64,7 @@ struct ladish_cqueue * ladish_studio_get_cmd_queue(void);
ladish_virtualizer_handle ladish_studio_get_virtualizer(void); ladish_virtualizer_handle ladish_studio_get_virtualizer(void);
ladish_graph_handle ladish_studio_get_jack_graph(void); ladish_graph_handle ladish_studio_get_jack_graph(void);
ladish_graph_handle ladish_studio_get_studio_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); bool ladish_studio_has_rooms(void);
unsigned int ladish_studio_get_room_index(void); unsigned int ladish_studio_get_room_index(void);

View File

@ -56,15 +56,16 @@ struct app_find_context
{ {
pid_t pid; pid_t pid;
char * app_name; char * app_name;
uuid_t app_uuid;
ladish_graph_handle graph; ladish_graph_handle graph;
}; };
#define app_find_context_ptr ((struct app_find_context *)context) #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; 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 */ 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; pid = app_find_context_ptr->pid;
do do
{ {
app_name = ladish_app_supervisor_search_app(app_supervisor, pid); app = ladish_app_supervisor_find_app_by_pid(app_supervisor, pid);
if (app_name != NULL) if (app != NULL)
break; break;
pid = (pid_t)procfs_get_process_parent((unsigned long long)pid); 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); while (pid != 0);
if (app_name != NULL) if (app == NULL)
{ { /* app not found in current supervisor */
app_find_context_ptr->app_name = app_name; return true; /* continue app supervisor iteration */
app_find_context_ptr->pid = pid;
app_find_context_ptr->graph = graph;
return false; /* stop app supervisor iteration */
} }
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
{
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 */
} }
#undef app_find_context_ptr #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; struct app_find_context context;
context.pid = (pid_t)pid; context.pid = (pid_t)pid;
context.app_name = NULL; context.app_name = NULL;
context.graph = 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) if (context.app_name != NULL)
{ {
ASSERT(context.graph != NULL); ASSERT(context.graph != NULL);
ASSERT(!uuid_is_null(context.app_uuid));
*graph_ptr = context.graph; *graph_ptr = context.graph;
uuid_copy(app_uuid, context.app_uuid);
} }
return context.app_name; 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; const char * a2j_name;
bool is_a2j; bool is_a2j;
char * app_name; char * app_name;
uuid_t app_uuid;
const char * name; const char * name;
pid_t pid; pid_t pid;
ladish_graph_handle graph; ladish_graph_handle graph;
@ -271,6 +285,7 @@ static void client_appeared(void * context, uint64_t id, const char * jack_name)
name = jack_name; name = jack_name;
app_name = NULL; app_name = NULL;
graph = NULL;
jmcore = false; jmcore = false;
if (!graph_proxy_get_client_pid(virtualizer_ptr->jack_graph_proxy, id, &pid)) 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 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) if (app_name != NULL)
{ {
log_info("app name is '%s'", app_name); 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 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) if (client != NULL)
@ -350,6 +370,8 @@ done:
if (app_name != NULL) if (app_name != NULL)
{ {
ladish_client_set_pid(client, pid); ladish_client_set_pid(client, pid);
ladish_client_set_app(client, app_uuid);
ASSERT(graph);
ladish_client_set_vgraph(client, graph); ladish_client_set_vgraph(client, graph);
virtualizer_ptr->our_clients_count++; virtualizer_ptr->our_clients_count++;
} }
@ -605,7 +627,7 @@ port_appeared(
if (is_a2j) 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 (vclient == NULL)
{ {
if (!ladish_client_create(NULL, &vclient)) if (!ladish_client_create(NULL, &vclient))
@ -621,7 +643,6 @@ port_appeared(
goto free_alsa_names; goto free_alsa_names;
} }
} }
} }
else if (client_id == virtualizer_ptr->system_client_id) else if (client_id == virtualizer_ptr->system_client_id)
{ {
@ -1052,6 +1073,7 @@ ladish_virtualizer_get_our_clients_count(
bool bool
ladish_virtualizer_is_hidden_app( ladish_virtualizer_is_hidden_app(
ladish_graph_handle jack_graph, ladish_graph_handle jack_graph,
const uuid_t app_uuid,
const char * app_name) const char * app_name)
{ {
ladish_client_handle jclient; ladish_client_handle jclient;
@ -1064,7 +1086,7 @@ ladish_virtualizer_is_hidden_app(
//ladish_graph_dump(g_studio.jack_graph); //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) if (jclient == NULL)
{ {
log_info("App without JACK client is treated as hidden one"); log_info("App without JACK client is treated as hidden one");
@ -1129,6 +1151,7 @@ ladish_virtualizer_is_hidden_app(
void void
ladish_virtualizer_remove_app( ladish_virtualizer_remove_app(
ladish_graph_handle jack_graph, ladish_graph_handle jack_graph,
const uuid_t app_uuid,
const char * app_name) const char * app_name)
{ {
ladish_client_handle jclient; ladish_client_handle jclient;
@ -1141,7 +1164,7 @@ ladish_virtualizer_remove_app(
//ladish_graph_dump(g_studio.jack_graph); //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) if (jclient == NULL)
{ {
log_info("removing app without JACK client"); log_info("removing app without JACK client");

View File

@ -51,13 +51,17 @@ ladish_virtualizer_get_our_clients_count(
bool bool
ladish_virtualizer_is_hidden_app( ladish_virtualizer_is_hidden_app(
ladish_graph_handle graph_hanle, ladish_graph_handle graph_hanle,
const uuid_t app_uuid,
const char * app_name); const char * app_name);
void void
ladish_virtualizer_remove_app( ladish_virtualizer_remove_app(
ladish_graph_handle graph_hanle, ladish_graph_handle graph_hanle,
const uuid_t app_uuid,
const char * app_name); const char * app_name);
void ladish_virtualizer_rename_app(void * context, const char * old_name, const char * new_app_name);
void void
ladish_virtualizer_destroy( ladish_virtualizer_destroy(
ladish_virtualizer_handle handle); ladish_virtualizer_handle handle);