daemon: wait room cleanup before destroying it. Fix for #81 and #83

This commit is contained in:
Nedko Arnaudov 2010-05-09 16:00:28 +03:00
parent b82728b36a
commit d8135a5117
4 changed files with 123 additions and 39 deletions

View File

@ -27,6 +27,7 @@
#include "cmd.h"
#include "studio_internal.h"
#include "../dbus/error.h"
#include "../proxies/jmcore_proxy.h"
struct ladish_command_delete_room
{
@ -34,6 +35,37 @@ struct ladish_command_delete_room
char * name;
};
static
bool
uninit_room_ports(
void * context,
void * client_iteration_context_ptr,
ladish_client_handle client_handle,
const char * client_name,
ladish_port_handle port_handle,
const char * port_name,
uint32_t port_type,
uint32_t port_flags)
{
uuid_t uuid_in_room;
char uuid_in_room_str[37];
if (ladish_port_is_link(port_handle))
{
log_info("link port %s", port_name);
ladish_graph_get_port_uuid(ladish_room_get_graph(context), port_handle, uuid_in_room);
uuid_unparse(uuid_in_room, uuid_in_room_str);
jmcore_proxy_destroy_link(uuid_in_room_str);
}
else
{
log_info("jack port %s", port_name);
}
return true;
}
#define cmd_ptr ((struct ladish_command_delete_room *)context)
static bool run(void * context)
@ -43,44 +75,78 @@ static bool run(void * context)
uuid_t room_uuid;
ladish_client_handle room_client;
unsigned int running_app_count;
ladish_app_supervisor_handle supervisor;
ladish_graph_handle graph;
ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING);
log_info("Delete studio room request (%s)", cmd_ptr->name);
if (cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING)
{
log_info("Delete studio room request (%s)", cmd_ptr->name);
}
list_for_each(node_ptr, &g_studio.rooms)
{
room = ladish_room_from_list_node(node_ptr);
if (strcmp(ladish_room_get_name(room), cmd_ptr->name) == 0)
{
running_app_count = ladish_app_supervisor_get_running_app_count(ladish_room_get_app_supervisor(room));
if (running_app_count != 0)
{
/* TODO: instead of rejecting the room deletion, use the command queue and wait for room apps to stop.
This requires proper "project in room" implementation because project needs to be
unloaded anyway and unloading project should initiate and wait apps termination */
log_error("Cannot delete room \"%s\" because it has %u app(s) running", cmd_ptr->name, running_app_count);
return false;
}
list_del(node_ptr);
ladish_studio_emit_room_disappeared(room);
ladish_room_get_uuid(room, room_uuid);
room_client = ladish_graph_find_client_by_uuid(g_studio.studio_graph, room_uuid);
ASSERT(room_client != NULL);
ladish_graph_remove_client(g_studio.studio_graph, room_client);
ladish_client_destroy(room_client);
ladish_room_destroy(room);
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
return true;
goto found;
}
}
log_error("Cannot delete room with name \"%s\" because it is unknown", cmd_ptr->name);
return false;
found:
supervisor = ladish_room_get_app_supervisor(room);
graph = ladish_room_get_graph(room);
ladish_room_get_uuid(room, room_uuid);
room_client = ladish_graph_find_client_by_uuid(g_studio.studio_graph, room_uuid);
ASSERT(room_client != NULL);
if (cmd_ptr->command.state == LADISH_COMMAND_STATE_PENDING)
{
ladish_graph_clear_persist(graph);
ladish_graph_iterate_nodes(ladish_room_get_graph(room), false, room, NULL, uninit_room_ports, NULL);
ladish_app_supervisor_stop(supervisor);
cmd_ptr->command.state = LADISH_COMMAND_STATE_WAITING;
return true;
}
ASSERT(cmd_ptr->command.state == LADISH_COMMAND_STATE_WAITING);
running_app_count = ladish_app_supervisor_get_running_app_count(supervisor);
if (running_app_count != 0)
{
log_info("there are %u running app(s) in room \"%s\"", running_app_count, cmd_ptr->name);
return true;
}
if (!ladish_graph_is_empty(graph))
{
log_info("the room \"%s\" graph is still not empty", cmd_ptr->name);
return true;
}
if (!ladish_graph_is_client_looks_empty(g_studio.studio_graph, room_client))
{
log_info("the room \"%s\" studio client still does not look empty", cmd_ptr->name);
return true;
}
/* ladish_graph_dump(graph); */
/* ladish_graph_dump(g_studio.studio_graph); */
/* ladish_graph_dump(g_studio.jack_graph); */
list_del(node_ptr);
ladish_studio_emit_room_disappeared(room);
ladish_graph_remove_client(g_studio.studio_graph, room_client);
ladish_client_destroy(room_client);
ladish_room_destroy(room);
cmd_ptr->command.state = LADISH_COMMAND_STATE_DONE;
return true;
}
static void destructor(void * context)

View File

@ -77,6 +77,7 @@ struct ladish_graph
uint64_t next_client_id;
uint64_t next_port_id;
uint64_t next_connection_id;
bool persist;
void * context;
ladish_graph_connect_request_handler connect_handler;
@ -640,6 +641,8 @@ bool ladish_graph_create(ladish_graph_handle * graph_handle_ptr, const char * op
graph_ptr->connect_handler = NULL;
graph_ptr->disconnect_handler = NULL;
graph_ptr->persist = true;
*graph_handle_ptr = (ladish_graph_handle)graph_ptr;
return true;
}
@ -2159,6 +2162,21 @@ void ladish_graph_dump(ladish_graph_handle graph_handle)
}
}
void ladish_graph_clear_persist(ladish_graph_handle graph_handle)
{
graph_ptr->persist = false;
}
bool ladish_graph_is_persist(ladish_graph_handle graph_handle)
{
return graph_ptr->persist;
}
bool ladish_graph_is_empty(ladish_graph_handle graph_handle)
{
return list_empty(&graph_ptr->clients) && list_empty(&graph_ptr->ports) && list_empty(&graph_ptr->connections);
}
#undef graph_ptr
#define graph_ptr ((struct ladish_graph *)context)

View File

@ -194,6 +194,10 @@ ladish_graph_iterate_connections(
void * callback_context,
bool (* callback)(void * context, ladish_port_handle port1_handle, ladish_port_handle port2_handle, ladish_dict_handle dict));
void ladish_graph_clear_persist(ladish_graph_handle graph_handle);
bool ladish_graph_is_persist(ladish_graph_handle graph_handle);
bool ladish_graph_is_empty(ladish_graph_handle graph_handle);
extern const struct dbus_interface_descriptor g_interface_patchbay;
#endif /* #ifndef PATCHBAY_H__30334B9A_8847_4E8C_AFF9_73DB13406C8E__INCLUDED */

View File

@ -375,6 +375,7 @@ static void client_disappeared(void * context, uint64_t id)
{
ladish_client_handle client;
pid_t pid;
ladish_graph_handle vgraph;
log_info("client_disappeared(%"PRIu64")", id);
@ -387,12 +388,7 @@ static void client_disappeared(void * context, uint64_t id)
log_info("client disappeared: '%s'", ladish_graph_get_client_name(virtualizer_ptr->jack_graph, client));
if (ladish_client_get_vgraph(client) == NULL)
{ /* remove jmcore clients, the are not persisted in the jack graph */
ladish_graph_remove_client(virtualizer_ptr->jack_graph, client);
ladish_client_destroy(client);
return;
}
vgraph = ladish_client_get_vgraph(client);
pid = ladish_client_get_pid(client);
if (pid != 0 && pid != jmcore_proxy_get_pid_cached())
@ -405,7 +401,7 @@ static void client_disappeared(void * context, uint64_t id)
virtualizer_ptr->system_client_id = 0;
}
if (true) /* if client is supposed to be persisted */
if (vgraph != NULL && ladish_graph_is_persist(vgraph)) /* if client is supposed to be persisted */
{
ladish_client_set_jack_id(client, 0);
ladish_graph_hide_client(virtualizer_ptr->jack_graph, client);
@ -743,15 +739,15 @@ static void port_disappeared(void * context, uint64_t client_id, uint64_t port_i
if (vgraph == NULL)
{
log_error("Cannot find vgraph for disappeared jmcore port");
ASSERT_NO_PASS;
return;
}
else
{
jmcore = true;
ladish_graph_remove_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true);
}
jmcore = true;
ladish_graph_remove_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true);
}
if (true) /* if client is supposed to be persisted */
if (ladish_graph_is_persist(vgraph)) /* if port is supposed to be persisted */
{
if (!jmcore)
{