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);
 }