summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2017-06-20 03:35:33 (GMT)
committerQi Wang <interwq@gmail.com>2017-06-21 00:47:38 (GMT)
commit37f3fa0941022d047fdcd86959d5f94f872e45e2 (patch)
treee11c0f2a0fb75a650e322b7b30b77f0744a42669 /src
parentd35c037e03e1450794dcf595e49a1e1f97f87ac4 (diff)
downloadjemalloc-37f3fa0941022d047fdcd86959d5f94f872e45e2.zip
jemalloc-37f3fa0941022d047fdcd86959d5f94f872e45e2.tar.gz
jemalloc-37f3fa0941022d047fdcd86959d5f94f872e45e2.tar.bz2
Mask signals during background thread creation.
This prevents signals from being inadvertently delivered to background threads.
Diffstat (limited to 'src')
-rw-r--r--src/background_thread.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/background_thread.c b/src/background_thread.c
index 1ff5944..f0aa04f 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);