[PATCH] bug fix for bearerbox signal handling

Alexander Malysh <[email protected]> (by way of Alexander Malysh <[email protected]>)
Newsgroups gmane.comp.mobile.kannel.devel
Organization Centrium GmbH
Message-ID <[email protected]>
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
bearerbox_signal_handling.diff (text/x-diff, 3.6 KB)
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)
 	;
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQA/ic8CnX3e5W+uJ0ERAsZnAKDhXVNM8W44puJHHtWj+E0pQIDeCwCePKkB
KKOWx3KyxqjSEa0fqqZmvkw=
=gbpq
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.