# HG changeset patch # User yaz # Date 1174318508 25200 # Node ID 021321cb5426a55515e90c0126e16adaa908279a # Parent 85acf3f98ed057270651b283d8656c508bfde863 [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. diff -r 85acf3f98ed0 -r 021321cb5426 ChangeLog --- 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 + 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 revision [4272] - performance is better without r4270. diff -r 85acf3f98ed0 -r 021321cb5426 src/audacious/build_stamp.c --- 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 -const gchar *svn_stamp = "20070317-4272"; +const gchar *svn_stamp = "20070317-4274"; diff -r 85acf3f98ed0 -r 021321cb5426 src/audacious/signals.c --- 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); }