[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