mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-02-03 18:49:28 -05:00
threads: backup commit for signal safe pthread_create
This commit is contained in:
parent
4d1bbe95ba
commit
c9ac095b0c
4 changed files with 116 additions and 0 deletions
|
|
@ -146,6 +146,8 @@ src/contrib/string.h
|
|||
src/contrib/strtonum.h
|
||||
src/contrib/time.c
|
||||
src/contrib/time.h
|
||||
src/contrib/threads.c
|
||||
src/contrib/threads.h
|
||||
src/contrib/toeplitz.h
|
||||
src/contrib/tolower.h
|
||||
src/contrib/trim.h
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ libcontrib_la_SOURCES = \
|
|||
contrib/strtonum.h \
|
||||
contrib/time.c \
|
||||
contrib/time.h \
|
||||
contrib/threads.c \
|
||||
contrib/threads.h \
|
||||
contrib/toeplitz.h \
|
||||
contrib/tolower.h \
|
||||
contrib/trim.h \
|
||||
|
|
|
|||
69
src/contrib/threads.c
Normal file
69
src/contrib/threads.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "contrib/threads.h"
|
||||
|
||||
typedef struct {
|
||||
const struct sigaction *sa;
|
||||
const sigset_t *sm;
|
||||
void *(*routine)(void *);
|
||||
void *arg;
|
||||
const int *signals;
|
||||
int nsignals;
|
||||
} sigsafe_arg_t;
|
||||
|
||||
static void *thread_create_sigsafe__impl(void *arg)
|
||||
{
|
||||
sigsafe_arg_t *sarg = arg;
|
||||
|
||||
// first set handlers, then unblock - order matters!
|
||||
for (int i = 0; i < sarg->nsignals; ++i) {
|
||||
sigaction(sarg->signals[i], sarg->sa, NULL);
|
||||
}
|
||||
pthread_sigmask(SIG_SETMASK, sarg->sm, NULL);
|
||||
|
||||
return sarg->routine(sarg->arg);
|
||||
}
|
||||
|
||||
int thread_create_sigsafe(pthread_t *restrict thr,
|
||||
const pthread_attr_t *restrict attr,
|
||||
const struct sigaction *sa,
|
||||
const sigset_t *sm,
|
||||
const int *signals,
|
||||
int nsignals,
|
||||
void *(*routine)(void *),
|
||||
void *restrict arg)
|
||||
{
|
||||
sigset_t mask;
|
||||
sigset_t oldmask;
|
||||
sigfillset(&mask);
|
||||
sigdelset(&mask, SIGBUS);
|
||||
sigdelset(&mask, SIGFPE);
|
||||
sigdelset(&mask, SIGILL);
|
||||
sigdelset(&mask, SIGSEGV);
|
||||
|
||||
// block all blockable signals
|
||||
pthread_sigmask(SIG_SETMASK, &mask, &oldmask);
|
||||
|
||||
// set desired sigmask and signal handler inside the thread through a wrapper function
|
||||
sigsafe_arg_t sarg = { sa, sm, routine, arg, signals, nsignals };
|
||||
int ret = pthread_create(thr, attr, thread_create_sigsafe__impl, &sarg);
|
||||
|
||||
// restore original sigmask
|
||||
pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
43
src/contrib/threads.h
Normal file
43
src/contrib/threads.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
/*!
|
||||
* \brief Spawn a new thread with different signal handling parameters without
|
||||
* risk of signal related race conditions.
|
||||
*
|
||||
* @param thr pthread_t structure
|
||||
* @param attr pthread_attr_t structure
|
||||
* @param sa struct sigaction handler to be used within the thread
|
||||
* @param sm sigset_t signal mask to be used within the thread
|
||||
* @param signals an array of signal numbers to which sigaction should be applied
|
||||
* @param nsignals ARR_LEN(signals)
|
||||
* @param routine thread entry function
|
||||
* @param arg thread argument
|
||||
* @returns return value of pthread_create
|
||||
*/
|
||||
int thread_create_sigsafe(pthread_t *restrict thr,
|
||||
const pthread_attr_t *restrict attr,
|
||||
const struct sigaction *sa,
|
||||
const sigset_t *sm,
|
||||
const int *signals,
|
||||
int nsignals,
|
||||
void *(*routine)(void *),
|
||||
void *restrict arg);
|
||||
Loading…
Reference in a new issue