aboutsummaryrefslogtreecommitdiffstats
path: root/lib/pthread_sigmask.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pthread_sigmask.c')
-rw-r--r--lib/pthread_sigmask.c40
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
24int 29int
25pthread_sigmask (int how, const sigset_t *new_mask, sigset_t *old_mask) 30pthread_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}