Hi List, attached patch corrects signal handling routine for bearerbox. We may not call mutex_[lock|unlock] or any not asynchron signal safe functions within a signal handler. Here is a quote from 'man pthread_mutex_lock':
ASYNC-SIGNAL SAFETY
The mutex functions are not async-signal safe. What this means is
that they should not be called from a signal handler. In particular,
calling pthread_mutex_lock or pthread_mutex_unlock from a signal handler
may deadlock the calling thread.
Generally for signal handler apply: make as little as possible within signal
handler function.
Comments and votes are very welcome...
--
Best regards / Mit besten Gr��en aus D�sseldorf
Dipl.-Ing.
Alexander Malysh
___________________________________
Centrium GmbH
Vogelsanger Weg 80
40470 D�sseldorf
Fon: +49 (0211) 74 84 51 80
Fax: +49 (0211) 277 49 109
email: a.malysh at centrium.de
web: http://www.centrium.de
msn: olek2002 at hotmail.com
icq: 98063111
___________________________________________
Please avoid sending me Word or PowerPoint attachments.
See http://www.fsf.org/philosophy/no-word-attachments.html
Index: gw/bearerbox.c
===================================================================
RCS file: /home/cvs/gateway/gw/bearerbox.c,v
retrieving revision 1.144
diff -a -u -r1.144 bearerbox.c
--- gw/bearerbox.c 7 Oct 2003 22:58:42 -0000 1.144
+++ gw/bearerbox.c 9 Oct 2003 15:36:10 -0000
@@ -60,6 +60,16 @@
volatile sig_atomic_t bb_status;
+/*
+ * Flags for main thread to check what is to do.
+ */
+enum {
+ BB_LOGREOPEN = 1,
+ BB_CHECKLEAKS = 2
+};
+/* Here we will set above flags */
+static volatile sig_atomic_t bb_todo = 0;
+
/* own global variables */
static Mutex *status_mutex;
@@ -99,28 +109,25 @@
switch (signum) {
case SIGINT:
case SIGTERM:
-
- mutex_lock(status_mutex);
if (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {
+ /* XXX warning should gone (not asynchron signal safe */
warning(0, "Killing signal received, shutting down...");
- mutex_unlock(status_mutex);
- bb_shutdown();
- return;
- }
+ bb_status = BB_SHUTDOWN;
+ }
else if (bb_status == BB_SHUTDOWN) {
+ /* XXX warning should gone (not asynchron signal safe */
warning(0, "New killing signal received, killing neverthless...");
bb_status = BB_DEAD;
}
else if (bb_status == BB_DEAD) {
- panic(0, "cannot die by its own will");
+ panic(0, "Cannot die by its own will");
}
- mutex_unlock(status_mutex);
break;
case SIGHUP:
+ /* XXX warning should gone (not asynchron signal safe */
warning(0, "SIGHUP received, catching and re-opening logs");
- log_reopen();
- alog_reopen();
+ bb_todo |= BB_LOGREOPEN;
break;
/*
@@ -128,9 +135,10 @@
* platforms that's reserved by the pthread support.
*/
case SIGQUIT:
- warning(0, "SIGQUIT received, reporting memory usage.");
- gw_check_leaks();
- break;
+ /* XXX warning should gone (not asynchron signal safe */
+ warning(0, "SIGQUIT received, reporting memory usage.");
+ bb_todo |= BB_CHECKLEAKS;
+ break;
}
}
@@ -513,8 +521,41 @@
list_remove_producer(isolated);
}
- /* wait until flow threads exit */
+ while(bb_status != BB_SHUTDOWN && bb_status != BB_DEAD && list_producer_count(flow_threads) > 0) {
+ debug("bb", 0, "Main Thread: going to sleep.");
+ /*
+ * Not infinite sleep here, because we should notice
+ * when all "flow threads" are dead and shutting bearerbox
+ * down.
+ * XXX if all "flow threads" call gwthread_wakeup(MAIN_THREAD_ID),
+ * we can enter infinite sleep then.
+ */
+ gwthread_sleep(10.0);
+ debug("bb", 0, "Main Thread: woken up.");
+
+ if (bb_todo == 0) {
+ debug("bb", 0, "Main Thread: Nothing todo.");
+ continue;
+ }
+ if (bb_todo & BB_LOGREOPEN) {
+ debug("bb", 0, "Main Thread: going to reopen log files.");
+ log_reopen();
+ alog_reopen();
+ bb_todo = bb_todo & ~BB_LOGREOPEN;
+ }
+
+ if (bb_todo & BB_CHECKLEAKS) {
+ debug("bb", 0, "Main Thread: going to checkleaks.");
+ gw_check_leaks();
+ bb_todo = bb_todo & ~BB_CHECKLEAKS;
+ }
+ }
+
+ /* call shutdown */
+ bb_shutdown();
+
+ /* wait until flow threads exit */
while(list_consume(flow_threads)!=NULL)
;
pgp00000.pgp
Description: signature
