Mask signals during background thread creation.
This prevents signals from being inadvertently delivered to background threads.
This commit is contained in:
parent
d35c037e03
commit
37f3fa0941
@ -22,6 +22,7 @@
|
|||||||
# include <sys/uio.h>
|
# include <sys/uio.h>
|
||||||
# endif
|
# endif
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
|
# include <signal.h>
|
||||||
# ifdef JEMALLOC_OS_UNFAIR_LOCK
|
# ifdef JEMALLOC_OS_UNFAIR_LOCK
|
||||||
# include <os/lock.h>
|
# include <os/lock.h>
|
||||||
# endif
|
# endif
|
||||||
|
@ -347,6 +347,38 @@ background_threads_disable_single(tsd_t *tsd, background_thread_info_t *info) {
|
|||||||
|
|
||||||
static void *background_thread_entry(void *ind_arg);
|
static void *background_thread_entry(void *ind_arg);
|
||||||
|
|
||||||
|
static int
|
||||||
|
background_thread_create_signals_masked(pthread_t *thread,
|
||||||
|
const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) {
|
||||||
|
/*
|
||||||
|
* Mask signals during thread creation so that the thread inherits
|
||||||
|
* an empty signal set.
|
||||||
|
*/
|
||||||
|
sigset_t set;
|
||||||
|
sigemptyset(&set);
|
||||||
|
sigset_t oldset;
|
||||||
|
int mask_err = pthread_sigmask(SIG_SETMASK, &set, &oldset);
|
||||||
|
if (mask_err != 0) {
|
||||||
|
return mask_err;
|
||||||
|
}
|
||||||
|
int create_err = pthread_create_wrapper(thread, attr, start_routine,
|
||||||
|
arg);
|
||||||
|
/*
|
||||||
|
* Restore the signal mask. Failure to restore the signal mask here
|
||||||
|
* changes program behavior.
|
||||||
|
*/
|
||||||
|
int restore_err = pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
if (restore_err != 0) {
|
||||||
|
malloc_printf("<jemalloc>: background thread creation "
|
||||||
|
"failed (%d), and signal mask restoration failed "
|
||||||
|
"(%d)\n", create_err, restore_err);
|
||||||
|
if (opt_abort) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return create_err;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_background_thread_creation(tsd_t *tsd, unsigned *n_created,
|
check_background_thread_creation(tsd_t *tsd, unsigned *n_created,
|
||||||
bool *created_threads) {
|
bool *created_threads) {
|
||||||
@ -377,8 +409,8 @@ label_restart:
|
|||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
|
||||||
|
|
||||||
pre_reentrancy(tsd);
|
pre_reentrancy(tsd);
|
||||||
int err = pthread_create_wrapper(&info->thread, NULL,
|
int err = background_thread_create_signals_masked(&info->thread,
|
||||||
background_thread_entry, (void *)(uintptr_t)i);
|
NULL, background_thread_entry, (void *)(uintptr_t)i);
|
||||||
post_reentrancy(tsd);
|
post_reentrancy(tsd);
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
@ -528,7 +560,7 @@ background_thread_create(tsd_t *tsd, unsigned arena_ind) {
|
|||||||
* To avoid complications (besides reentrancy), create internal
|
* To avoid complications (besides reentrancy), create internal
|
||||||
* background threads with the underlying pthread_create.
|
* background threads with the underlying pthread_create.
|
||||||
*/
|
*/
|
||||||
int err = pthread_create_wrapper(&info->thread, NULL,
|
int err = background_thread_create_signals_masked(&info->thread, NULL,
|
||||||
background_thread_entry, (void *)thread_ind);
|
background_thread_entry, (void *)thread_ind);
|
||||||
post_reentrancy(tsd);
|
post_reentrancy(tsd);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user