diff options
| author | Jason Evans <jasone@canonware.com> | 2017-06-19 20:35:33 -0700 |
|---|---|---|
| committer | Qi Wang <interwq@gmail.com> | 2017-06-20 17:47:38 -0700 |
| commit | 37f3fa0941022d047fdcd86959d5f94f872e45e2 (patch) | |
| tree | e11c0f2a0fb75a650e322b7b30b77f0744a42669 | |
| parent | d35c037e03e1450794dcf595e49a1e1f97f87ac4 (diff) | |
| download | platform_external_jemalloc_new-37f3fa0941022d047fdcd86959d5f94f872e45e2.tar.gz platform_external_jemalloc_new-37f3fa0941022d047fdcd86959d5f94f872e45e2.tar.bz2 platform_external_jemalloc_new-37f3fa0941022d047fdcd86959d5f94f872e45e2.zip | |
Mask signals during background thread creation.
This prevents signals from being inadvertently delivered to background
threads.
| -rw-r--r-- | include/jemalloc/internal/jemalloc_internal_decls.h | 1 | ||||
| -rw-r--r-- | src/background_thread.c | 38 |
2 files changed, 36 insertions, 3 deletions
diff --git a/include/jemalloc/internal/jemalloc_internal_decls.h b/include/jemalloc/internal/jemalloc_internal_decls.h index 1efdb56b..8ae5ef48 100644 --- a/include/jemalloc/internal/jemalloc_internal_decls.h +++ b/include/jemalloc/internal/jemalloc_internal_decls.h @@ -22,6 +22,7 @@ # include <sys/uio.h> # endif # include <pthread.h> +# include <signal.h> # ifdef JEMALLOC_OS_UNFAIR_LOCK # include <os/lock.h> # endif diff --git a/src/background_thread.c b/src/background_thread.c index 1ff59447..f0aa04f3 100644 --- a/src/background_thread.c +++ b/src/background_thread.c @@ -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 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 check_background_thread_creation(tsd_t *tsd, unsigned *n_created, bool *created_threads) { @@ -377,8 +409,8 @@ label_restart: malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock); pre_reentrancy(tsd); - int err = pthread_create_wrapper(&info->thread, NULL, - background_thread_entry, (void *)(uintptr_t)i); + int err = background_thread_create_signals_masked(&info->thread, + NULL, background_thread_entry, (void *)(uintptr_t)i); post_reentrancy(tsd); if (err == 0) { @@ -528,7 +560,7 @@ background_thread_create(tsd_t *tsd, unsigned arena_ind) { * To avoid complications (besides reentrancy), create internal * 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); post_reentrancy(tsd); |
