Mercurial > audlegacy
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 } |