From 960ef493a406365148185b1e108a353e71d2795c Mon Sep 17 00:00:00 2001 From: normal Date: Thu, 16 Aug 2018 08:26:51 +0000 Subject: thread_pthread.c: check signals from gvl.timer For (rare) blocking functions which are not affected by signals, we need to call the appropriate unblocking function via `threadptr_trap_interrupt' While we're at it, handling waitpid/SIGCHLD from gvl.timer isn't harmful, here. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64388 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- thread_pthread.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'thread_pthread.c') diff --git a/thread_pthread.c b/thread_pthread.c index 1f2cff3b12..cd7a512d9e 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -121,6 +121,7 @@ static const struct timespec *sigwait_timeout(rb_thread_t *, int sigwait_fd, const struct timespec *, int *drained_p); static void ubf_timer_disarm(void); +static void threadptr_trap_interrupt(rb_thread_t *); #define TIMER_THREAD_CREATED_P() (signal_self_pipe.owner_process == getpid()) @@ -193,7 +194,21 @@ do_gvl_timer(rb_vm_t *vm, rb_thread_t *th) vm->gvl.timer = th; err = native_cond_timedwait(&nd->cond.gvlq, &vm->gvl.lock, &ts); vm->gvl.timer = 0; + ubf_wakeup_all_threads(); + ruby_sigchld_handler(vm); + if (UNLIKELY(rb_signal_buff_size())) { + if (th == vm->main_thread) { + RUBY_VM_SET_TRAP_INTERRUPT(th->ec); + } + else { + /* unlock is needed because threadptr_trap_interrupt may + * call ubf_select which also acquires vm->gvl.lock */ + rb_native_mutex_unlock(&vm->gvl.lock); + threadptr_trap_interrupt(vm->main_thread); + rb_native_mutex_lock(&vm->gvl.lock); + } + } /* * Timeslice. Warning: the process may fork while this -- cgit v1.2.3