comparison src/audacious/signals.c @ 2677:52785bdac597 trunk

[svn] - workaround for linuxthread's broken implementation of sigwait().
author yaz
date Thu, 12 Apr 2007 00:16:37 -0700
parents f3ee0b78150a
children 182aa34ae6c4
comparison
equal deleted inserted replaced
2676:936c777ad998 2677:52785bdac597
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA. 17 * 02110-1301, USA.
18 */ 18 */
19 19
20 #define _XOPEN_SOURCE 20 //#define _XOPEN_SOURCE
21 #include <unistd.h> /* for signal_check_for_broken_impl() */ 21 #include <unistd.h> /* for signal_check_for_broken_impl() */
22 22
23 #include <glib.h> 23 #include <glib.h>
24 #include <glib/gi18n.h> 24 #include <glib/gi18n.h>
25 #include <glib/gprintf.h> 25 #include <glib/gprintf.h>
38 #include "main.h" 38 #include "main.h"
39 #include "ui_main.h" 39 #include "ui_main.h"
40 #include "signals.h" 40 #include "signals.h"
41 #include "build_stamp.h" 41 #include "build_stamp.h"
42 42
43 gint linuxthread_signal_number = 0;
44
43 static void 45 static void
44 signal_process_segv(void) 46 signal_process_segv(void)
45 { 47 {
46 g_printerr(_("\nAudacious has caught signal 11 (SIGSEGV).\n\n" 48 g_printerr(_("\nAudacious has caught signal 11 (SIGSEGV).\n\n"
47 "We apologize for the inconvenience, but Audacious has crashed.\n" 49 "We apologize for the inconvenience, but Audacious has crashed.\n"
121 } 123 }
122 124
123 return NULL; //dummy 125 return NULL; //dummy
124 } 126 }
125 127
128 /********************************************************************************/
129 /* for linuxthread */
130 /********************************************************************************/
131
132 typedef void (*SignalHandler) (gint);
133
134 static void *
135 signal_process_signals_linuxthread (void *data)
136 {
137 while(1) {
138 g_usleep(1000000);
139
140 switch(linuxthread_signal_number){
141 case SIGPIPE:
142 /*
143 * do something.
144 */
145 linuxthread_signal_number = 0;
146 break;
147
148 case SIGSEGV:
149 signal_process_segv();
150 break;
151
152 case SIGINT:
153 g_print("Audacious has received SIGINT and is shutting down.\n");
154 mainwin_quit_cb();
155 break;
156
157 case SIGTERM:
158 g_print("Audacious has received SIGTERM and is shutting down.\n");
159 mainwin_quit_cb();
160 break;
161 }
162 }
163
164 return NULL; //dummy
165 }
166
167 static void
168 linuxthread_handler (gint signal_number)
169 {
170 /* note: cannot manipulate mutex from signal handler */
171 linuxthread_signal_number = signal_number;
172 }
173
174 static SignalHandler
175 signal_install_handler_full (gint signal_number,
176 SignalHandler handler,
177 gint *signals_to_block,
178 gsize n_signals)
179 {
180 struct sigaction action, old_action;
181 gsize i;
182
183 action.sa_handler = handler;
184 action.sa_flags = SA_RESTART;
185
186 sigemptyset (&action.sa_mask);
187
188 for (i = 0; i < n_signals; i++)
189 sigaddset (&action.sa_mask, signals_to_block[i]);
190
191 if (sigaction (signal_number, &action, &old_action) == -1)
192 {
193 g_message ("Failed to install handler for signal %d", signal_number);
194 return NULL;
195 }
196
197 return old_action.sa_handler;
198 }
199
200 /*
201 * A version of signal() that works more reliably across different
202 * platforms. It:
203 * a. restarts interrupted system calls
204 * b. does not reset the handler
205 * c. blocks the same signal within the handler
206 *
207 * (adapted from Unix Network Programming Vol. 1)
208 */
209 static SignalHandler
210 signal_install_handler (gint signal_number,
211 SignalHandler handler)
212 {
213 return signal_install_handler_full (signal_number, handler, NULL, 0);
214 }
215
216
126 /* sets up blocking signals for pthreads. 217 /* sets up blocking signals for pthreads.
127 * linuxthreads sucks and needs this to make sigwait(2) work 218 * linuxthreads sucks and needs this to make sigwait(2) work
128 * correctly. --nenolod 219 * correctly. --nenolod
129 * 220 *
130 * correction -- this trick does not work on linuxthreads. 221 * correction -- this trick does not work on linuxthreads.
168 { 259 {
169 signal_initialize_blockers(); 260 signal_initialize_blockers();
170 g_thread_create(signal_process_signals, NULL, FALSE, NULL); 261 g_thread_create(signal_process_signals, NULL, FALSE, NULL);
171 } 262 }
172 else 263 else
264 {
173 g_printerr(_("Your signaling implementation is broken.\n" 265 g_printerr(_("Your signaling implementation is broken.\n"
174 "Expect unusable crash reports.\n")); 266 "Expect unusable crash reports.\n"));
175 } 267
268 /* install special handler which catches signals and forwards to the signal handling thread */
269 signal_install_handler(SIGPIPE, linuxthread_handler);
270 signal_install_handler(SIGSEGV, linuxthread_handler);
271 signal_install_handler(SIGINT, linuxthread_handler);
272 signal_install_handler(SIGTERM, linuxthread_handler);
273
274 /* create handler thread */
275 g_thread_create(signal_process_signals_linuxthread, NULL, FALSE, NULL);
276
277 }
278 }