ladishd: better handling for L1 apps with a2j ports. Fix for #62
This commit is contained in:
parent
d65ebbbf5b
commit
891805634d
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains implementation of app supervisor object
|
||||
|
@ -50,6 +50,7 @@ struct ladish_app
|
|||
pid_t pgrp;
|
||||
pid_t firstborn_pid;
|
||||
pid_t firstborn_pgrp;
|
||||
int firstborn_refcount;
|
||||
bool zombie; /* if true, remove when stopped */
|
||||
bool autorun;
|
||||
unsigned int state;
|
||||
|
@ -288,6 +289,7 @@ ladish_app_supervisor_add(
|
|||
app_ptr->pgrp = 0;
|
||||
app_ptr->firstborn_pid = 0;
|
||||
app_ptr->firstborn_pgrp = 0;
|
||||
app_ptr->firstborn_refcount = 0;
|
||||
|
||||
app_ptr->id = supervisor_ptr->next_id++;
|
||||
if (uuid == NULL || uuid_is_null(uuid))
|
||||
|
@ -349,6 +351,13 @@ static void ladish_app_send_signal(struct ladish_app * app_ptr, int sig, bool pr
|
|||
}
|
||||
}
|
||||
|
||||
if (app_ptr->pid == 0)
|
||||
{
|
||||
log_error("not sending signal %d (%s) to app '%s' because its pid is %d", sig, signal_name, app_ptr->name, (int)app_ptr->pid);
|
||||
ASSERT_NO_PASS;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
case SIGKILL:
|
||||
|
@ -553,8 +562,9 @@ bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_ha
|
|||
|
||||
app_ptr->pid = 0;
|
||||
app_ptr->pgrp = 0;
|
||||
app_ptr->firstborn_pid = 0;
|
||||
app_ptr->firstborn_pgrp = 0;
|
||||
/* firstborn pid and pgrp is not reset here because it is refcounted
|
||||
and managed independently through the add/del_pid() methods */
|
||||
|
||||
if (app_ptr->zombie)
|
||||
{
|
||||
remove_app_internal(supervisor_ptr, app_ptr);
|
||||
|
@ -700,20 +710,33 @@ void ladish_app_add_pid(ladish_app_handle app_handle, pid_t pid)
|
|||
|
||||
if (app_ptr->firstborn_pid != 0)
|
||||
{ /* Ignore non-first children */
|
||||
if (app_ptr->firstborn_pid == pid)
|
||||
{
|
||||
app_ptr->firstborn_refcount++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("First grandchild with pid %u", (unsigned int)pid);
|
||||
app_ptr->firstborn_pid = pid;
|
||||
ASSERT(app_ptr->firstborn_refcount == 0);
|
||||
app_ptr->firstborn_refcount = 1;
|
||||
}
|
||||
|
||||
void ladish_app_del_pid(ladish_app_handle app_handle, pid_t pid)
|
||||
{
|
||||
if (app_ptr->firstborn_pid != 0 && app_ptr->firstborn_pid == pid)
|
||||
{
|
||||
ASSERT(app_ptr->firstborn_refcount > 0);
|
||||
app_ptr->firstborn_refcount--;
|
||||
if (app_ptr->firstborn_refcount > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
log_info("First grandchild with pid %u has gone", (unsigned int)pid);
|
||||
app_ptr->firstborn_pid = 0;
|
||||
app_ptr->firstborn_pgrp = 0;
|
||||
app_ptr->firstborn_refcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains the implementation of the port objects
|
||||
|
@ -36,6 +36,8 @@ struct ladish_port
|
|||
uint64_t jack_id; /* JACK port ID. */
|
||||
uint64_t jack_id_room; /* JACK port ID in room. valid only for link ports */
|
||||
|
||||
pid_t pid; /* process id. */
|
||||
|
||||
void * vgraph; /* virtual graph */
|
||||
|
||||
ladish_dict_handle dict;
|
||||
|
@ -203,4 +205,14 @@ bool ladish_port_belongs_to_app(ladish_port_handle port_handle, const uuid_t app
|
|||
return uuid_compare(port_ptr->app_uuid, app_uuid) == 0;
|
||||
}
|
||||
|
||||
void ladish_port_set_pid(ladish_port_handle port_handle, pid_t pid)
|
||||
{
|
||||
port_ptr->pid = pid;
|
||||
}
|
||||
|
||||
pid_t ladish_port_get_pid(ladish_port_handle port_handle)
|
||||
{
|
||||
return port_ptr->pid;
|
||||
}
|
||||
|
||||
#undef port_ptr
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains the interface of the port objects
|
||||
|
@ -55,4 +55,7 @@ bool ladish_port_get_app(ladish_port_handle port, uuid_t app_uuid);
|
|||
bool ladish_port_has_app(ladish_port_handle port);
|
||||
bool ladish_port_belongs_to_app(ladish_port_handle port, const uuid_t app_uuid);
|
||||
|
||||
void ladish_port_set_pid(ladish_port_handle port_handle, pid_t pid);
|
||||
pid_t ladish_port_get_pid(ladish_port_handle port_handle);
|
||||
|
||||
#endif /* #ifndef PORT_H__62F81E7C_91FA_44AB_94A9_E0E2D226ED58__INCLUDED */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* LADI Session Handler (ladish)
|
||||
*
|
||||
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
*
|
||||
**************************************************************************
|
||||
* This file contains implementation of the graph virtualizer object
|
||||
|
@ -576,6 +576,7 @@ port_appeared(
|
|||
vclient_name = ladish_app_get_name(app);
|
||||
has_app = true;
|
||||
log_info("ALSA app name is '%s'", vclient_name);
|
||||
ladish_app_add_pid(app, pid);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -637,6 +638,7 @@ port_appeared(
|
|||
if (has_app)
|
||||
{
|
||||
ladish_port_set_app(port, app_uuid);
|
||||
ladish_port_set_pid(port, pid);
|
||||
if (!ladish_client_has_app(vclient))
|
||||
{
|
||||
ladish_client_set_app(vclient, app_uuid);
|
||||
|
@ -666,6 +668,7 @@ port_appeared(
|
|||
if (has_app)
|
||||
{
|
||||
ladish_port_set_app(port, app_uuid);
|
||||
ladish_port_set_pid(port, pid);
|
||||
}
|
||||
|
||||
ladish_dict_set(ladish_port_get_dict(port), URI_A2J_PORT, is_a2j ? "yes" : "no");
|
||||
|
@ -825,6 +828,28 @@ exit:
|
|||
return;
|
||||
}
|
||||
|
||||
static void maybe_clear_a2j_port_pid(ladish_graph_handle vgraph, ladish_client_handle jclient, ladish_port_handle port)
|
||||
{
|
||||
const char * opath;
|
||||
uuid_t app_uuid;
|
||||
ladish_app_handle app;
|
||||
ladish_app_supervisor_handle app_supervisor;
|
||||
pid_t pid;
|
||||
|
||||
if (ladish_virtualizer_is_a2j_client(jclient) && ladish_port_get_app(port, app_uuid))
|
||||
{
|
||||
pid = ladish_port_get_pid(port);
|
||||
opath = ladish_graph_get_opath(vgraph);
|
||||
log_info("releasing reference for pid %d of a2j port in %s", (int)pid, ladish_graph_get_description(vgraph));
|
||||
app_supervisor = ladish_studio_find_app_supervisor(opath);
|
||||
app = ladish_app_supervisor_find_app_by_uuid(app_supervisor, app_uuid);
|
||||
if (app != NULL && pid != 0)
|
||||
{
|
||||
ladish_app_del_pid(app, pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void port_disappeared(void * context, uint64_t client_id, uint64_t port_id)
|
||||
{
|
||||
ladish_client_handle jclient;
|
||||
|
@ -865,6 +890,12 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i
|
|||
jmcore = true;
|
||||
ladish_graph_remove_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
maybe_clear_a2j_port_pid(vgraph, jclient, port);
|
||||
}
|
||||
|
||||
ladish_port_set_pid(port, 0);
|
||||
|
||||
if (ladish_graph_is_persist(vgraph)) /* if port is supposed to be persisted */
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue