Mercurial > audlegacy
changeset 2629:021321cb5426 trunk
[svn] simplify and enhance signal handler:
- implement an independent signal processing thread using sigwait().
- new signal thread can always generate meaningful back trace. (AUD_ENSURE_BACKTRACE is no longer needed.)
- this thread is also capable of dumping config file upon receiving SIGSEGV. (but not yet tested thoroughly).
- g_cond_signal() has been removed. however g_cond_signal() can be used safely within the signal thread. the former implementation depended on an indefinite behavior of pthread.
author | yaz |
---|---|
date | Mon, 19 Mar 2007 08:35:08 -0700 |
parents | 85acf3f98ed0 |
children | e7e1df8afffb |
files | ChangeLog src/audacious/build_stamp.c src/audacious/signals.c |
diffstat | 3 files changed, 54 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Mar 16 19:21:54 2007 -0700 +++ b/ChangeLog Mon Mar 19 08:35:08 2007 -0700 @@ -1,3 +1,10 @@ +2007-03-17 02:21:54 +0000 Giacomo Lozito <james@develia.org> + revision [4274] + - prevent skin list overlap when it's populated for the first time and user quickly switchs to other tabs in the prefswin + trunk/src/audacious/ui_preferences.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + + 2007-03-17 02:07:19 +0000 William Pitcock <nenolod@sacredspiral.co.uk> revision [4272] - performance is better without r4270.
--- a/src/audacious/build_stamp.c Fri Mar 16 19:21:54 2007 -0700 +++ b/src/audacious/build_stamp.c Mon Mar 19 08:35:08 2007 -0700 @@ -1,2 +1,2 @@ #include <glib.h> -const gchar *svn_stamp = "20070317-4272"; +const gchar *svn_stamp = "20070317-4274";
--- a/src/audacious/signals.c Fri Mar 16 19:21:54 2007 -0700 +++ b/src/audacious/signals.c Mon Mar 19 08:35:08 2007 -0700 @@ -33,117 +33,65 @@ #include "ui_main.h" #include "signals.h" -GCond *exit_cond; -GMutex *exit_mutex; - -typedef void (*SignalHandler) (gint); - -static SignalHandler -signal_install_handler_full (gint signal_number, - SignalHandler handler, - gint *signals_to_block, - gsize n_signals) +static void * +signal_process_signals (void *data) { - struct sigaction action, old_action; - gsize i; + sigset_t waitset; + int sig; + + sigemptyset(&waitset); + sigaddset(&waitset, SIGPIPE); + sigaddset(&waitset, SIGSEGV); + sigaddset(&waitset, SIGINT); + sigaddset(&waitset, SIGTERM); - action.sa_handler = handler; - action.sa_flags = SA_RESTART; + while(1) { + sigwait(&waitset, &sig); - sigemptyset (&action.sa_mask); + switch(sig){ + case SIGPIPE: + /* + * do something. + */ + break; - for (i = 0; i < n_signals; i++) - sigaddset (&action.sa_mask, signals_to_block[i]); + case SIGSEGV: + g_printerr(_("\nReceived SIGSEGV\n\n" + "This could be a bug in Audacious. If you don't know why this happened, " + "file a bug at http://bugs-meta.atheme.org/\n\n")); + g_critical("Received SIGSEGV"); + bmp_config_save(); + abort(); + break; - if (sigaction (signal_number, &action, &old_action) == -1) - { - g_message ("Failed to install handler for signal %d", signal_number); - return NULL; + case SIGINT: + g_print("Audacious has received SIGINT and is shutting down.\n"); + mainwin_quit_cb(); + break; + + case SIGTERM: + g_print("Audacious has received SIGTERM and is shutting down.\n"); + mainwin_quit_cb(); + break; + } } - return old_action.sa_handler; -} - -/* - * A version of signal() that works more reliably across different - * platforms. It: - * a. restarts interrupted system calls - * b. does not reset the handler - * c. blocks the same signal within the handler - * - * (adapted from Unix Network Programming Vol. 1) - */ -static SignalHandler -signal_install_handler (gint signal_number, - SignalHandler handler) -{ - return signal_install_handler_full (signal_number, handler, NULL, 0); -} - -static void -signal_empty_handler (gint signal_number) -{ - /* empty */ -} - -static void -sigsegv_handler (gint signal_number) -{ -#ifndef SIGSEGV_ABORT - g_printerr(_("\nReceived SIGSEGV\n\n" - "This could be a bug in Audacious. If you don't know why this happened, " - "file a bug at http://bugs-meta.atheme.org/\n\n")); - g_critical("Received SIGSEGV"); - - /* TO DO: log stack trace and possibly dump config file. */ - exit (EXIT_FAILURE); -#else - abort (); -#endif -} - -static void -sigterm_handler (gint signal_number) -{ - cfg.terminate = TRUE; - g_cond_signal(exit_cond); -} - -static void * -signal_process_events (void *data) -{ - while (1) { - if (cfg.terminate == TRUE) - { - g_print("Audacious has received SIGTERM and is shutting down.\n"); - mainwin_quit_cb(); - } - g_mutex_lock(exit_mutex); - g_cond_wait(exit_cond, exit_mutex); - g_mutex_unlock(exit_mutex); - } - - return NULL; + return NULL; //dummy } void signal_handlers_init (void) { - char *magic; - magic = getenv("AUD_ENSURE_BACKTRACE"); - - exit_cond = g_cond_new(); - exit_mutex = g_mutex_new(); + sigset_t blockset; - signal_install_handler(SIGPIPE, signal_empty_handler); - signal_install_handler(SIGINT, sigterm_handler); - signal_install_handler(SIGTERM, sigterm_handler); + sigemptyset(&blockset); + sigaddset(&blockset, SIGPIPE); + sigaddset(&blockset, SIGSEGV); + sigaddset(&blockset, SIGINT); + sigaddset(&blockset, SIGTERM); - /* in particular environment (maybe with glibc 2.5), core file - through signal handler doesn't contain useful back trace. --yaz */ - if (magic == NULL) - signal_install_handler(SIGSEGV, sigsegv_handler); + if(pthread_sigmask(SIG_BLOCK, &blockset, NULL)) + g_print("pthread_sigmask() failed.\n"); - g_thread_create(signal_process_events, NULL, FALSE, NULL); - + g_thread_create(signal_process_signals, NULL, FALSE, NULL); }