Skip to content
Snippets Groups Projects
Verified Commit 29342e97 authored by Jan Doskočil's avatar Jan Doskočil
Browse files

WIP: signal safe pthread_create

parent 3f7ba562
No related branches found
No related tags found
No related merge requests found
Pipeline #129482 passed
#include "contrib/threads.h"
typedef struct {
const struct sigaction *sa;
const sigset_t *sm;
void *(*routine)(void *);
void *arg;
const int *signals;
int nsignals;
} thrd_sigsafe_arg_t;
static void *thread_create_sigsafe__impl(void *arg)
{
thrd_sigsafe_arg_t *targ = arg;
for (int i = 0; i < targ->nsignals; ++i) {
sigaction(targ->signals[i], targ->sa, NULL);
}
pthread_sigmask(SIG_SETMASK, targ->sm, NULL);
return targ->routine(targ->arg);
}
int thread_create_sigsafe(pthread_t *restrict thr,
pthread_attr_t *restrict attr,
const struct sigaction *sa,
const sigset_t *sm,
const int *signals,
int nsignals,
void *(*routine)(void *),
void *arg)
{
thrd_sigsafe_arg_t targ = { sa, sm, routine, arg, signals, nsignals };
int ret;
SIG_PROTECT_BEGIN;
ret = pthread_create(thr, attr, thread_create_sigsafe__impl, &targ);
SIG_PROTECT_END;
return ret;
}
#pragma once
#include <pthread.h>
#include <signal.h>
/* block signals */
#define SIG_PROTECT_BEGIN \
do { \
sigset_t SIG_PROTECT__mask; \
sigset_t SIG_PROTECT__oldmask; \
sigfillset(&SIG_PROTECT__mask); \
\
/* blocking these is a bad idea */ \
sigdelset(&SIG_PROTECT__mask, SIGBUS); \
sigdelset(&SIG_PROTECT__mask, SIGFPE); \
sigdelset(&SIG_PROTECT__mask, SIGILL); \
sigdelset(&SIG_PROTECT__mask, SIGSEGV); \
\
pthread_sigmask(SIG_SETMASK, &SIG_PROTECT__mask, &SIG_PROTECT__oldmask)
/* ...do whatever needs to be done then unblock them again */
#define SIG_PROTECT_END \
pthread_sigmask(SIG_SETMASK, &SIG_PROTECT__oldmask, NULL); \
} while (0)
/* Spawn a new thread without risk of signal related race conditions.
*
* thr - pthread_t structure
* attr - pthread_attr_t structure
* sa - struct sigaction handler to be used within the thread
* sm - sigset_t signal mask to be used within the thread
* signals - an array of signal numbers to which sigaction should be applied
* nsignals - ARR_LEN(signals)
* routine - thread entry function
* arg - thread argument
*/
int thread_create_sigsafe(pthread_t *restrict thr,
pthread_attr_t *restrict attr,
const struct sigaction *sa,
const sigset_t *sm,
const int *signals,
int nsignals,
void *(*routine)(void *),
void *arg);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment