diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-16 08:26:51 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-08-16 08:26:51 +0000 |
commit | 960ef493a406365148185b1e108a353e71d2795c (patch) | |
tree | 179f2687dac95751e4cef077eb49b3e94922a0b4 | |
parent | 0783fd936602dfc0c04a91d22f95dd4a1fb21f3a (diff) |
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
-rw-r--r-- | thread_pthread.c | 15 |
1 files changed, 15 insertions, 0 deletions
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 |