aboutsummaryrefslogtreecommitdiffstats
path: root/thread_pthread.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-30 02:28:00 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-30 02:28:00 +0000
commitdd5697ffbf8668bee686b85f4100034fc5a046b1 (patch)
tree16b866e502903675005fc18409542ea18c5577fb /thread_pthread.c
parent8f24f049dd8953f0fb65748bed33f6391b951048 (diff)
downloadruby-dd5697ffbf8668bee686b85f4100034fc5a046b1.tar.gz
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.c42
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