Skip to content

Commit d857d7f

Browse files
committed
SR-4201: DispatchSourceSignal not working on Linux
The observed bug is that signals sent to the main thread after it called dispatch_main were not triggering the event handler of a DispatchSourceSignal that had been previously created and activated to handle that signal. If plausible signals are added to the sigsuspend mask, then they are properly routed to the signalfd and the DispatchSourceSignal event handler runs as expected. This commit also changes event_epoll to use pthread_sigmask to block the signal when creating a signalfd because the Linux man page for sigprocmask states that sigprocmask's behavior is undefined for multi-threaded programs and pthread_sigmask should be used instead.
1 parent 7ca0a63 commit d857d7f

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/event/event_epoll.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
135135
if (fd < 0) {
136136
return NULL;
137137
}
138-
sigprocmask(SIG_BLOCK, &sigmask, NULL);
138+
pthread_sigmask(SIG_BLOCK, &sigmask, NULL);
139139
break;
140140

141141
case EVFILT_WRITE:

src/queue.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5762,7 +5762,25 @@ DISPATCH_NOINLINE DISPATCH_NORETURN
57625762
static void
57635763
_dispatch_sigsuspend(void)
57645764
{
5765-
static const sigset_t mask;
5765+
sigset_t mask;
5766+
int r;
5767+
5768+
r = sigemptyset(&mask);
5769+
(void)dispatch_assume_zero(r);
5770+
5771+
#if DISPATCH_EVENT_BACKEND_EPOLL
5772+
// If there are signals that the user may have reasonably
5773+
// created a DispatchSignalSource to monitor and might
5774+
// reasonably be sent to the main thread after it has called
5775+
// dispatch_main, we have to include them in the sigsuspend mask
5776+
// or they won't be properly delivered to the signalfd.
5777+
r = sigaddset(&mask, SIGUSR1);
5778+
(void)dispatch_assume_zero(r);
5779+
r = sigaddset(&mask, SIGUSR2);
5780+
(void)dispatch_assume_zero(r);
5781+
r = sigaddset(&mask, SIGCHLD);
5782+
(void)dispatch_assume_zero(r);
5783+
#endif
57665784

57675785
for (;;) {
57685786
sigsuspend(&mask);

0 commit comments

Comments
 (0)