Skip to content

Commit

Permalink
mq_notify: block all (application) signals in the worker thread
Browse files Browse the repository at this point in the history
until the mq notification event arrives, it is mandatory that signals
be blocked. otherwise, a signal can be received, and its handler
executed, in a thread which does not yet exist on the abstract
machine.

after the point of the event arriving, having signals blocked is not a
conformance requirement but a QoI requirement. while the application
can unblock any signals it wants unblocked in the event handler
thread, if they did not start out blocked, it could not block them
without a race window where they are momentarily unblocked, and this
would preclude controlled delivery or other forms of acceptance
(sigwait, etc.) anywhere in the application.
  • Loading branch information
richfelker committed Feb 12, 2023
1 parent 711673e commit 0ab9735
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/mq/mq_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev)
pthread_t td;
int s;
int cs;
sigset_t allmask, origmask;

if (!sev || sev->sigev_notify != SIGEV_THREAD)
return syscall(SYS_mq_notify, mqd, sev);
Expand All @@ -64,11 +65,15 @@ int mq_notify(mqd_t mqd, const struct sigevent *sev)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
sem_init(&args.sem, 0, 0);

sigfillset(&allmask);
pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
if (pthread_create(&td, &attr, start, &args)) {
__syscall(SYS_close, s);
pthread_sigmask(SIG_SETMASK, &origmask, 0);
errno = EAGAIN;
return -1;
}
pthread_sigmask(SIG_SETMASK, &origmask, 0);

pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
sem_wait(&args.sem);
Expand Down

0 comments on commit 0ab9735

Please sign in to comment.