diff options
| author | Stefan Monnier | 2012-03-25 16:37:21 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-03-25 16:37:21 -0400 |
| commit | 699c782b7668c44d0fa4446331b0590a6d5dac82 (patch) | |
| tree | 5dcce364741d0761920a3d274b0fc8aba4103d45 /lib/pthread_sigmask.c | |
| parent | 98fb480ee31bf74cf554044f60f21df16566dd7f (diff) | |
| parent | e99a9b8bdccadded1f6fae88ee7a2a93dfd4eacf (diff) | |
| download | emacs-pending.tar.gz emacs-pending.zip | |
Merge from trunkpending
Diffstat (limited to 'lib/pthread_sigmask.c')
| -rw-r--r-- | lib/pthread_sigmask.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/pthread_sigmask.c b/lib/pthread_sigmask.c index 1f460f13c48..11d549cad41 100644 --- a/lib/pthread_sigmask.c +++ b/lib/pthread_sigmask.c | |||
| @@ -20,10 +20,50 @@ | |||
| 20 | #include <signal.h> | 20 | #include <signal.h> |
| 21 | 21 | ||
| 22 | #include <errno.h> | 22 | #include <errno.h> |
| 23 | #include <stddef.h> | ||
| 24 | |||
| 25 | #if PTHREAD_SIGMASK_UNBLOCK_BUG | ||
| 26 | # include <unistd.h> | ||
| 27 | #endif | ||
| 23 | 28 | ||
| 24 | int | 29 | int |
| 25 | pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) | 30 | pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) |
| 31 | #undef pthread_sigmask | ||
| 26 | { | 32 | { |
| 33 | #if HAVE_PTHREAD_SIGMASK | ||
| 34 | int ret = pthread_sigmask (how, new_mask, old_mask); | ||
| 35 | # if PTHREAD_SIGMASK_INEFFECTIVE | ||
| 36 | if (ret == 0) | ||
| 37 | { | ||
| 38 | /* Detect whether pthread_sigmask is currently ineffective. | ||
| 39 | Don't cache the information: libpthread.so could be dynamically | ||
| 40 | loaded after the program started and after pthread_sigmask was | ||
| 41 | called for the first time. */ | ||
| 42 | if (pthread_sigmask (1729, NULL, NULL) == 0) | ||
| 43 | { | ||
| 44 | /* pthread_sigmask is currently ineffective. The program is not | ||
| 45 | linked to -lpthread. So use sigprocmask instead. */ | ||
| 46 | return (sigprocmask (how, new_mask, old_mask) < 0 ? errno : 0); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | # endif | ||
| 50 | # if PTHREAD_SIGMASK_FAILS_WITH_ERRNO | ||
| 51 | if (ret == -1) | ||
| 52 | return errno; | ||
| 53 | # endif | ||
| 54 | # if PTHREAD_SIGMASK_UNBLOCK_BUG | ||
| 55 | if (ret == 0 | ||
| 56 | && new_mask != NULL | ||
| 57 | && (how == SIG_UNBLOCK || how == SIG_SETMASK)) | ||
| 58 | { | ||
| 59 | /* Give the OS the opportunity to raise signals that were pending before | ||
| 60 | the pthread_sigmask call and have now been unblocked. */ | ||
| 61 | usleep (1); | ||
| 62 | } | ||
| 63 | # endif | ||
| 64 | return ret; | ||
| 65 | #else | ||
| 27 | int ret = sigprocmask (how, new_mask, old_mask); | 66 | int ret = sigprocmask (how, new_mask, old_mask); |
| 28 | return (ret < 0 ? errno : 0); | 67 | return (ret < 0 ? errno : 0); |
| 68 | #endif | ||
| 29 | } | 69 | } |