summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-16 08:26:51 (GMT)
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-16 08:26:51 (GMT)
commit960ef493a406365148185b1e108a353e71d2795c (patch)
tree179f2687dac95751e4cef077eb49b3e94922a0b4 /thread_pthread.c
parent0783fd936602dfc0c04a91d22f95dd4a1fb21f3a (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
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/thread_pthread.c b/thread_pthread.c
index 1f2cff3..cd7a512 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