# HG changeset patch # User yaz # Date 1176362197 25200 # Node ID 52785bdac59719be9cd6833b094400104affe99c # Parent 936c777ad9980d22794dc3edf1ba03b68289f6a1 [svn] - workaround for linuxthread's broken implementation of sigwait(). diff -r 936c777ad998 -r 52785bdac597 ChangeLog --- a/ChangeLog Wed Apr 11 00:28:41 2007 -0700 +++ b/ChangeLog Thu Apr 12 00:16:37 2007 -0700 @@ -1,3 +1,11 @@ +2007-04-11 07:28:41 +0000 Yoshiki Yazawa + revision [4378] + - unsigned char should be used during id3v1 parse. closes #888. + + trunk/src/libid3tag/tag.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + + 2007-04-10 21:17:31 +0000 William Pitcock revision [4376] - chase r4268 (patch by Joker) diff -r 936c777ad998 -r 52785bdac597 src/audacious/build_stamp.c --- a/src/audacious/build_stamp.c Wed Apr 11 00:28:41 2007 -0700 +++ b/src/audacious/build_stamp.c Thu Apr 12 00:16:37 2007 -0700 @@ -1,2 +1,2 @@ #include -const gchar *svn_stamp = "20070410-4376"; +const gchar *svn_stamp = "20070411-4378"; diff -r 936c777ad998 -r 52785bdac597 src/audacious/signals.c --- a/src/audacious/signals.c Wed Apr 11 00:28:41 2007 -0700 +++ b/src/audacious/signals.c Thu Apr 12 00:16:37 2007 -0700 @@ -17,7 +17,7 @@ * 02110-1301, USA. */ -#define _XOPEN_SOURCE +//#define _XOPEN_SOURCE #include /* for signal_check_for_broken_impl() */ #include @@ -40,6 +40,8 @@ #include "signals.h" #include "build_stamp.h" +gint linuxthread_signal_number = 0; + static void signal_process_segv(void) { @@ -123,6 +125,95 @@ return NULL; //dummy } +/********************************************************************************/ +/* for linuxthread */ +/********************************************************************************/ + +typedef void (*SignalHandler) (gint); + +static void * +signal_process_signals_linuxthread (void *data) +{ + while(1) { + g_usleep(1000000); + + switch(linuxthread_signal_number){ + case SIGPIPE: + /* + * do something. + */ + linuxthread_signal_number = 0; + break; + + case SIGSEGV: + signal_process_segv(); + break; + + 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 NULL; //dummy +} + +static void +linuxthread_handler (gint signal_number) +{ + /* note: cannot manipulate mutex from signal handler */ + linuxthread_signal_number = signal_number; +} + +static SignalHandler +signal_install_handler_full (gint signal_number, + SignalHandler handler, + gint *signals_to_block, + gsize n_signals) +{ + struct sigaction action, old_action; + gsize i; + + action.sa_handler = handler; + action.sa_flags = SA_RESTART; + + sigemptyset (&action.sa_mask); + + for (i = 0; i < n_signals; i++) + sigaddset (&action.sa_mask, signals_to_block[i]); + + if (sigaction (signal_number, &action, &old_action) == -1) + { + g_message ("Failed to install handler for signal %d", signal_number); + return NULL; + } + + 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); +} + + /* sets up blocking signals for pthreads. * linuxthreads sucks and needs this to make sigwait(2) work * correctly. --nenolod @@ -170,6 +261,18 @@ g_thread_create(signal_process_signals, NULL, FALSE, NULL); } else + { g_printerr(_("Your signaling implementation is broken.\n" "Expect unusable crash reports.\n")); + + /* install special handler which catches signals and forwards to the signal handling thread */ + signal_install_handler(SIGPIPE, linuxthread_handler); + signal_install_handler(SIGSEGV, linuxthread_handler); + signal_install_handler(SIGINT, linuxthread_handler); + signal_install_handler(SIGTERM, linuxthread_handler); + + /* create handler thread */ + g_thread_create(signal_process_signals_linuxthread, NULL, FALSE, NULL); + + } }