properly handle ladishd crashes

This commit is contained in:
Nedko Arnaudov 2009-12-17 07:41:57 +02:00
parent cd80903ecf
commit bf9b9272cb
6 changed files with 117 additions and 8 deletions

View File

@ -294,16 +294,21 @@ static void ladish_exit(struct dbus_method_call * call_ptr)
method_return_new_void(call_ptr);
}
void emit_studio_appeared()
void emit_studio_appeared(void)
{
dbus_signal_emit(g_dbus_connection, CONTROL_OBJECT_PATH, INTERFACE_NAME, "StudioAppeared", "");
}
void emit_studio_disappeared()
void emit_studio_disappeared(void)
{
dbus_signal_emit(g_dbus_connection, CONTROL_OBJECT_PATH, INTERFACE_NAME, "StudioDisappeared", "");
}
void emit_clean_exit(void)
{
dbus_signal_emit(g_dbus_connection, CONTROL_OBJECT_PATH, INTERFACE_NAME, "CleanExit", "");
}
METHOD_ARGS_BEGIN(IsStudioLoaded, "Check whether studio D-Bus object is present")
METHOD_ARG_DESCRIBE_OUT("present", "b", "Whether studio D-Bus object is present")
METHOD_ARGS_END
@ -348,9 +353,13 @@ SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN(StudioDisappeared, "Studio D-Bus object disappeared")
SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN(CleanExit, "Exit was requested")
SIGNAL_ARGS_END
SIGNALS_BEGIN
SIGNAL_DESCRIBE(StudioAppeared)
SIGNAL_DESCRIBE(StudioDisappeared)
SIGNAL_DESCRIBE(CleanExit)
SIGNALS_END
/*

View File

@ -30,7 +30,8 @@
extern const struct dbus_interface_descriptor g_lashd_interface_control;
void emit_studio_appeared();
void emit_studio_disappeared();
void emit_studio_appeared(void);
void emit_studio_disappeared(void);
void emit_clean_exit(void);
#endif /* __LASHD_DBUS_IFACE_CONTROL_H__ */

View File

@ -301,6 +301,8 @@ int main(int argc, char ** argv, char ** envp)
studio_run();
}
emit_clean_exit();
ret = EXIT_SUCCESS;
log_debug("Finished, cleaning up");

View File

@ -74,15 +74,18 @@ graph_view_handle g_jack_view = NULL;
graph_view_handle g_studio_view = NULL;
static guint g_jack_poll_source_tag;
static guint g_ladishd_poll_source_tag;
static double g_jack_max_dsp_load = 0.0;
#define STUDIO_STATE_NA 0
#define STUDIO_STATE_UNKNOWN 0
#define STUDIO_STATE_UNLOADED 1
#define STUDIO_STATE_STOPPED 2
#define STUDIO_STATE_STARTED 3
#define STUDIO_STATE_CRASHED 4
#define STUDIO_STATE_NA 5
#define STUDIO_STATE_SICK 6
static unsigned int g_studio_state = STUDIO_STATE_UNLOADED;
static unsigned int g_studio_state = STUDIO_STATE_UNKNOWN;
#define JACK_STATE_NA 0
#define JACK_STATE_STOPPED 1
@ -495,6 +498,12 @@ static gboolean poll_jack(gpointer data)
return TRUE;
}
static gboolean poll_ladishd(gpointer data)
{
control_proxy_ping();
return TRUE;
}
bool studio_state_changed(char ** name_ptr_ptr)
{
const char * status;
@ -533,6 +542,9 @@ bool studio_state_changed(char ** name_ptr_ptr)
switch (g_studio_state)
{
case STUDIO_STATE_NA:
name = "ladishd is down";
break;
case STUDIO_STATE_SICK:
name = "ladishd is sick";
break;
case STUDIO_STATE_UNLOADED:
@ -576,6 +588,43 @@ bool studio_state_changed(char ** name_ptr_ptr)
return true;
}
void control_proxy_on_daemon_appeared(void)
{
if (g_studio_state == STUDIO_STATE_NA || g_studio_state == STUDIO_STATE_SICK)
{
log_info("ladishd appeared");
g_source_remove(g_ladishd_poll_source_tag);
}
g_studio_state = STUDIO_STATE_UNLOADED;
studio_state_changed(NULL);
}
void control_proxy_on_daemon_disappeared(bool clean_exit)
{
log_info("ladishd disappeared");
if (!clean_exit)
{
error_message_box("ladish daemon crashed");
g_studio_state = STUDIO_STATE_SICK;
}
else
{
g_studio_state = STUDIO_STATE_NA;
}
studio_state_changed(NULL);
if (g_studio_view != NULL)
{
destroy_view(g_studio_view);
g_studio_view = NULL;
}
g_ladishd_poll_source_tag = g_timeout_add(500, poll_ladishd, NULL);
}
void control_proxy_on_studio_appeared(void)
{
char * name;
@ -657,9 +706,12 @@ void jack_started(void)
void jack_stopped(void)
{
log_info("JACK stopped");
if (g_jack_state == JACK_STATE_STARTED)
{
log_info("JACK stopped");
g_source_remove(g_jack_poll_source_tag);
g_source_remove(g_jack_poll_source_tag);
}
g_jack_state = JACK_STATE_STOPPED;
studio_state_changed(NULL);

View File

@ -27,6 +27,8 @@
#include "control_proxy.h"
static bool g_clean_exit;
static void on_studio_appeared(void * context, DBusMessage * message_ptr)
{
log_info("StudioAppeared");
@ -39,12 +41,18 @@ static void on_studio_disappeared(void * context, DBusMessage * message_ptr)
control_proxy_on_studio_disappeared();
}
static void on_clean_exit(void * context, DBusMessage * message_ptr)
{
g_clean_exit = true;
}
/* this must be static because it is referenced by the
* dbus helper layer when hooks are active */
static struct dbus_signal_hook g_signal_hooks[] =
{
{"StudioAppeared", on_studio_appeared},
{"StudioDisappeared", on_studio_disappeared},
{"CleanExit", on_clean_exit},
{NULL, NULL}
};
@ -62,12 +70,36 @@ static bool control_proxy_is_studio_loaded(bool * present_ptr)
return true;
}
void on_lifestatus_changed(bool appeared)
{
if (appeared)
{
control_proxy_on_daemon_appeared();
}
else
{
control_proxy_on_daemon_disappeared(g_clean_exit);
}
g_clean_exit = false;
}
bool control_proxy_init(void)
{
bool studio_present;
g_clean_exit = false;
if (!control_proxy_is_studio_loaded(&studio_present))
{
return true;
}
control_proxy_on_daemon_appeared();
if (!dbus_register_service_lifetime_hook(g_dbus_connection, SERVICE_NAME, on_lifestatus_changed))
{
control_proxy_on_daemon_disappeared(true);
return false;
}
@ -84,6 +116,8 @@ bool control_proxy_init(void)
control_proxy_on_studio_disappeared();
}
control_proxy_on_daemon_disappeared(true);
return false;
}
@ -93,6 +127,14 @@ bool control_proxy_init(void)
void control_proxy_uninit(void)
{
dbus_unregister_object_signal_hooks(g_dbus_connection, SERVICE_NAME, CONTROL_OBJECT_PATH, IFACE_CONTROL);
dbus_unregister_service_lifetime_hook(g_dbus_connection, SERVICE_NAME);
}
void control_proxy_ping(void)
{
bool studio_present;
control_proxy_is_studio_loaded(&studio_present);
}
bool control_proxy_get_studio_list(void (* callback)(void * context, const char * studio_name), void * context)

View File

@ -32,6 +32,8 @@
bool control_proxy_init(void);
void control_proxy_uninit(void);
void control_proxy_on_daemon_appeared(void);
void control_proxy_on_daemon_disappeared(bool clean_exit);
void control_proxy_on_studio_appeared(void);
void control_proxy_on_studio_disappeared(void);
bool control_proxy_get_studio_list(void (* callback)(void * context, const char * studio_name), void * context);
@ -39,5 +41,6 @@ bool control_proxy_new_studio(const char * studio_name);
bool control_proxy_load_studio(const char * studio_name);
bool control_proxy_delete_studio(const char * studio_name);
bool control_proxy_exit(void);
void control_proxy_ping(void);
#endif /* #ifndef CONTROL_PROXY_H__8BC89E98_FE1B_4831_8B89_1A48F676E019__INCLUDED */