notify user when JACK crashes or stops unexpectedly

This commit is contained in:
Nedko Arnaudov 2009-12-17 06:34:45 +02:00
parent 128590f5bf
commit 1e9d406f23
4 changed files with 173 additions and 59 deletions

View File

@ -103,12 +103,17 @@ studio_publish(void)
return true;
}
void emit_studio_started()
void emit_studio_started(void)
{
dbus_signal_emit(g_dbus_connection, STUDIO_OBJECT_PATH, IFACE_STUDIO, "StudioStarted", "");
}
void emit_studio_stopped()
void emit_studio_crashed(void)
{
dbus_signal_emit(g_dbus_connection, STUDIO_OBJECT_PATH, IFACE_STUDIO, "StudioCrashed", "");
}
void emit_studio_stopped(void)
{
dbus_signal_emit(g_dbus_connection, STUDIO_OBJECT_PATH, IFACE_STUDIO, "StudioStopped", "");
}
@ -147,10 +152,8 @@ void on_event_jack_started(void)
emit_studio_started();
}
void on_event_jack_stopped(void)
static void on_jack_stopped_internal(void)
{
emit_studio_stopped();
if (g_studio.automatic)
{
log_info("Unloading automatic studio.");
@ -171,8 +174,17 @@ void on_event_jack_stopped(void)
}
}
void on_event_jack_stopped(void)
{
emit_studio_stopped();
on_jack_stopped_internal();
}
void handle_unexpected_jack_server_stop(void)
{
emit_studio_crashed();
on_jack_stopped_internal();
/* TODO: if user wants, restart jack server and reconnect all jack apps to it */
}
@ -215,7 +227,6 @@ void studio_run(void)
* the change will be consumed by the run method of the studio stop command */
log_error("JACK stopped unexpectedly.");
log_error("Save your work, then unload and reload the studio.");
on_event_jack_stopped();
handle_unexpected_jack_server_stop();
}
}
@ -234,7 +245,6 @@ void studio_run(void)
ladish_graph_clear(g_studio.studio_graph, false);
ladish_graph_clear(g_studio.jack_graph, true);
on_event_jack_stopped();
handle_unexpected_jack_server_stop();
}
}
@ -680,6 +690,9 @@ SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN(StudioStarted, "Studio started")
SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN(StudioCrashed, "Studio crashed")
SIGNAL_ARGS_END
SIGNAL_ARGS_BEGIN(StudioStopped, "Studio stopped")
SIGNAL_ARGS_END
@ -694,6 +707,7 @@ SIGNAL_ARGS_END
SIGNALS_BEGIN
SIGNAL_DESCRIBE(StudioRenamed)
SIGNAL_DESCRIBE(StudioStarted)
SIGNAL_DESCRIBE(StudioCrashed)
SIGNAL_DESCRIBE(StudioStopped)
SIGNAL_DESCRIBE(RoomAppeared)
SIGNAL_DESCRIBE(RoomDisappeared)

View File

@ -75,8 +75,20 @@ graph_view_handle g_studio_view = NULL;
static guint g_jack_poll_source_tag;
static double g_jack_max_dsp_load = 0.0;
static bool g_studio_started = false;
static bool g_studio_loaded = false;
#define STUDIO_STATE_NA 0
#define STUDIO_STATE_UNLOADED 1
#define STUDIO_STATE_STOPPED 2
#define STUDIO_STATE_STARTED 3
#define STUDIO_STATE_CRASHED 4
static unsigned int g_studio_state = STUDIO_STATE_UNLOADED;
#define JACK_STATE_NA 0
#define JACK_STATE_STOPPED 1
#define JACK_STATE_STARTED 2
static unsigned int g_jack_state = JACK_STATE_NA;
struct studio_list
{
@ -483,68 +495,118 @@ static gboolean poll_jack(gpointer data)
return TRUE;
}
void studio_state_changed(void)
bool studio_state_changed(char ** name_ptr_ptr)
{
gtk_widget_set_sensitive(g_menu_item_start_studio, g_studio_loaded);
gtk_widget_set_sensitive(g_menu_item_stop_studio, g_studio_loaded);
gtk_widget_set_sensitive(g_menu_item_save_studio, g_studio_loaded && g_studio_started);
gtk_widget_set_sensitive(g_menu_item_unload_studio, g_studio_loaded);
gtk_widget_set_sensitive(g_menu_item_rename_studio, g_studio_loaded);
gtk_widget_set_sensitive(g_menu_item_start_app, g_studio_loaded);
const char * status;
const char * name;
char * buffer;
gtk_widget_set_sensitive(g_menu_item_start_studio, g_studio_state == STUDIO_STATE_STOPPED);
gtk_widget_set_sensitive(g_menu_item_stop_studio, g_studio_state == STUDIO_STATE_STARTED);
gtk_widget_set_sensitive(g_menu_item_save_studio, g_studio_state == STUDIO_STATE_STARTED);
gtk_widget_set_sensitive(g_menu_item_unload_studio, g_studio_state != STUDIO_STATE_UNLOADED);
gtk_widget_set_sensitive(g_menu_item_rename_studio, g_studio_state == STUDIO_STATE_STOPPED || g_studio_state == STUDIO_STATE_STARTED);
gtk_widget_set_sensitive(g_menu_item_start_app, g_studio_state == STUDIO_STATE_STOPPED || g_studio_state == STUDIO_STATE_STARTED);
//gtk_widget_set_sensitive(g_menu_item_create_room, g_studio_loaded);
//gtk_widget_set_sensitive(g_menu_item_destroy_room, g_studio_loaded);
//gtk_widget_set_sensitive(g_menu_item_load_project, g_studio_loaded);
gtk_label_set_text(GTK_LABEL(g_studio_status_label), name);
switch (g_jack_state)
{
case JACK_STATE_NA:
status = "JACK is sick";
break;
case JACK_STATE_STOPPED:
status = "Stopped";
break;
case JACK_STATE_STARTED:
status = "xruns";
break;
default:
status = "???";
}
buffer = NULL;
switch (g_studio_state)
{
case STUDIO_STATE_NA:
name = "ladishd is sick";
break;
case STUDIO_STATE_UNLOADED:
name = "No studio loaded";
break;
case STUDIO_STATE_CRASHED:
status = "Crashed";
/* fall through */
case STUDIO_STATE_STOPPED:
case STUDIO_STATE_STARTED:
if (!studio_proxy_get_name(&buffer))
{
log_error("failed to get studio name");
}
else
{
name = buffer;
break;
}
default:
name = "???";
}
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(g_xrun_progress_bar), status);
gtk_label_set_text(GTK_LABEL(g_studio_status_label), name);
if (buffer == NULL)
{
return false;
}
if (name_ptr_ptr != NULL)
{
*name_ptr_ptr = buffer;
}
else
{
free(buffer);
}
return true;
}
void control_proxy_on_studio_appeared(void)
{
char * name;
char * name;
g_studio_loaded = true;
if (!studio_proxy_get_name(&name))
g_studio_state = STUDIO_STATE_STOPPED;
if (studio_state_changed(&name))
{
log_error("failed to get studio name");
goto exit;
if (g_studio_view != NULL)
{
log_error("studio appear signal received but studio already exists");
}
else if (!create_view(name, SERVICE_NAME, STUDIO_OBJECT_PATH, true, true, false, &g_studio_view))
{
log_error("create_view() failed for studio");
}
free(name);
}
if (g_studio_view != NULL)
{
log_error("studio appear signal received but studio already exists");
goto free_name;
}
if (!create_view(name, SERVICE_NAME, STUDIO_OBJECT_PATH, true, true, false, &g_studio_view))
{
log_error("create_view() failed for studio");
goto free_name;
}
studio_state_changed();
gtk_label_set_text(GTK_LABEL(g_studio_status_label), name);
free_name:
free(name);
exit:
return;
}
void control_proxy_on_studio_disappeared(void)
{
g_studio_state = STUDIO_STATE_UNLOADED;
studio_state_changed(NULL);
if (g_studio_view == NULL)
{
log_error("studio disappear signal received but studio does not exists");
return;
}
g_studio_loaded = false;
studio_state_changed();
gtk_label_set_text(GTK_LABEL(g_studio_status_label), "No studio loaded");
if (g_studio_view != NULL)
{
destroy_view(g_studio_view);
@ -557,16 +619,35 @@ static void on_studio_renamed(const char * new_studio_name)
if (g_studio_view != NULL)
{
set_view_name(g_studio_view, new_studio_name);
gtk_label_set_text(GTK_LABEL(g_studio_status_label), new_studio_name);
}
}
void on_studio_started(void)
{
g_studio_state = STUDIO_STATE_STARTED;
studio_state_changed(NULL);
}
void on_studio_stopped(void)
{
g_studio_state = STUDIO_STATE_STOPPED;
studio_state_changed(NULL);
}
void on_studio_crashed(void)
{
g_studio_state = STUDIO_STATE_CRASHED;
studio_state_changed(NULL);
error_message_box("JACK crashed or stopped unexpectedly. Save your work, then unload and reload the studio.");
}
void jack_started(void)
{
log_info("JACK started");
g_studio_started = true;
studio_state_changed();
g_jack_state = JACK_STATE_STARTED;
studio_state_changed(NULL);
gtk_widget_set_sensitive(g_buffer_size_combo, true);
gtk_widget_set_sensitive(g_clear_load_button, true);
@ -578,23 +659,24 @@ void jack_stopped(void)
{
log_info("JACK stopped");
g_studio_started = false;
g_source_remove(g_jack_poll_source_tag);
studio_state_changed();
g_jack_state = JACK_STATE_STOPPED;
studio_state_changed(NULL);
gtk_widget_set_sensitive(g_buffer_size_combo, false);
buffer_size_clear();
gtk_widget_set_sensitive(g_clear_load_button, false);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(g_xrun_progress_bar), 0.0);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(g_xrun_progress_bar), "Stopped");
}
void jack_appeared(void)
{
log_info("JACK appeared");
g_jack_state = JACK_STATE_STOPPED;
studio_state_changed(NULL);
#if defined(SHOW_RAW_JACK)
if (!create_view("Raw JACK", JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH, false, false, true, &g_jack_view))
{
@ -610,6 +692,9 @@ void jack_disappeared(void)
jack_stopped();
g_jack_state = JACK_STATE_NA;
studio_state_changed(NULL);
#if defined(SHOW_RAW_JACK)
if (g_jack_view != NULL)
{
@ -765,6 +850,8 @@ int main(int argc, char** argv)
return 1;
}
studio_proxy_set_startstop_callbacks(on_studio_started, on_studio_stopped, on_studio_crashed);
studio_proxy_set_renamed_callback(on_studio_renamed);
set_buffer_size_combo_width();

View File

@ -30,6 +30,7 @@
static void (* g_renamed_callback)(const char * new_studio_name) = NULL;
static void (* g_started_callback)(void) = NULL;
static void (* g_stopped_callback)(void) = NULL;
static void (* g_crashed_callback)(void) = NULL;
static void on_studio_renamed(void * context, DBusMessage * message_ptr)
{
@ -71,6 +72,16 @@ static void on_studio_stopped(void * context, DBusMessage * message_ptr)
}
}
static void on_studio_crashed(void * context, DBusMessage * message_ptr)
{
log_info("StudioCrashed");
if (g_crashed_callback != NULL)
{
g_crashed_callback();
}
}
static void on_room_appeared(void * context, DBusMessage * message_ptr)
{
log_info("RoomAppeared");
@ -88,6 +99,7 @@ static struct dbus_signal_hook g_signal_hooks[] =
{"StudioRenamed", on_studio_renamed},
{"StudioStarted", on_studio_started},
{"StudioStopped", on_studio_stopped},
{"StudioCrashed", on_studio_crashed},
{"RoomAppeared", on_room_appeared},
{"RoomDisappeared", on_room_disappeared},
{NULL, NULL}
@ -153,10 +165,11 @@ void studio_proxy_set_renamed_callback(void (* callback)(const char * new_studio
g_renamed_callback = callback;
}
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void))
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void), void (* crashed_callback)(void))
{
g_started_callback = started_callback;
g_stopped_callback = stopped_callback;
g_crashed_callback = crashed_callback;
}
bool studio_proxy_start(void)

View File

@ -38,7 +38,7 @@ bool studio_proxy_save(void);
bool studio_proxy_unload(void);
void studio_proxy_set_renamed_callback(void (* callback)(const char * new_studio_name));
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void));
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void), void (* crashed_callback)(void));
bool studio_proxy_start(void);
bool studio_proxy_stop(void);