diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-30 02:28:00 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-30 02:28:00 +0000 |
commit | 26b8a70bb309c7a367b9134045508b5b5a580a77 (patch) | |
tree | 16b866e502903675005fc18409542ea18c5577fb /thread_pthread.c | |
parent | 3dc7727d22fecbc355597edda25d2a245bf55ba1 (diff) |
thread_pthread.c (rb_sigwait_sleep): re-fix [Bug #5343] harder
We can't always designate a timer thread, so any sleepers must
also perform ubf wakeups. Note: a similar change needs to be
made for rb_thread_fd_select and rb_wait_for_single_fd.
[ruby-core:88088] [Misc #14937] [Bug #5343]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_pthread.c')
-rw-r--r-- | thread_pthread.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/thread_pthread.c b/thread_pthread.c index c1cfe531f0..8f63da2e93 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1613,11 +1613,45 @@ rb_sigwait_sleep(rb_thread_t *th, int sigwait_fd, const struct timespec *ts) { struct pollfd pfd; - pfd.fd = sigwait_fd; - pfd.events = POLLIN; + if (ubf_threads_empty()) { + pfd.fd = sigwait_fd; + pfd.events = POLLIN; + (void)ppoll(&pfd, 1, ts, 0); + check_signals_nogvl(th, sigwait_fd); + } + else { + static const struct timespec quantum = { 0, TIME_QUANTUM_USEC * 1000 }; + struct timespec *endp = 0, end, now; + + if (ts) { + getclockofday(&end); + timespec_add(&end, ts); + endp = &end; + } + + getclockofday(&now); + for (;;) { + const struct timespec *tsp = &quantum; + struct timespec diff; + int n; + + if (endp) { + diff = *endp; + timespec_sub(&diff, &now); + if (timespec_cmp(&diff, tsp) < 0) + tsp = &diff; + } - (void)ppoll(&pfd, 1, ts, 0); - check_signals_nogvl(th, sigwait_fd); + n = ppoll(&pfd, 1, tsp, 0); + check_signals_nogvl(th, sigwait_fd); + if (RUBY_VM_INTERRUPTED(th->ec) || n != 0) break; + + if (endp) { + getclockofday(&now); + if (timespec_cmp(&now, endp) >= 0) break; + } + } + } } static void |