[Xcb] [libpthread-stubs] fix semaphore signal safety

Samuel Thibault samuel.thibault at ens-lyon.org
Sat Sep 26 06:52:56 PDT 2009


Hello,

I've just realized that sem_post() is allowed to be called from a signal
handler, so the semaphore implementation has to be signal-safe, here is
a patch.

Samuel
Please keep me in Cc, I'm not subscribed to the list.
-------------- next part --------------
--- libpthread-stubs-0.2/stubs.c.orig	2009-09-26 15:29:16.000000000 +0200
+++ libpthread-stubs-0.2/stubs.c	2009-09-26 15:47:20.000000000 +0200
@@ -27,6 +27,7 @@
 #include <pthread.h>
 #include <errno.h>
 #include <semaphore.h>
+#include <signal.h>
 #include "config.h"
 
 #ifndef HAVE_PTHREAD_SELF
@@ -210,13 +211,14 @@
 static int __sem_wait_stub(sem_t *_sem)
 {
     unsigned int *sem = (unsigned int *) _sem;
-    if (!*sem) {
-	/* Not available, simulate a blocking sem_wait */
-	pause();
-	errno = EINTR;
-	return -1;
-    }
-    *sem--;
+    sigset_t set, oldset;
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, &oldset);
+    while (!*sem)
+	/* Not available, wait for a potential sem_post in signal handler */
+	sigsuspend(&oldset);
+    (*sem)--;
+    sigprocmask(SIG_SETMASK, &oldset, NULL);
     return 0;
 }
 #endif
@@ -225,11 +227,16 @@
 static int __sem_trywait_stub(sem_t *_sem)
 {
     unsigned int *sem = (unsigned int *) _sem;
+    sigset_t set, oldset;
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, &oldset);
     if (!*sem) {
+	sigprocmask(SIG_SETMASK, &oldset, NULL);
 	errno = EAGAIN;
 	return -1;
     }
-    *sem--;
+    (*sem)--;
+    sigprocmask(SIG_SETMASK, &oldset, NULL);
     return 0;
 }
 #endif
@@ -238,7 +245,11 @@
 static int __sem_post_stub(sem_t *_sem)
 {
     unsigned int *sem = (unsigned int *) _sem;
-    *sem++;
+    sigset_t set, oldset;
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, &oldset);
+    (*sem)++;
+    sigprocmask(SIG_SETMASK, &oldset, NULL);
     return 0;
 }
 #endif


More information about the Xcb mailing list