ruby-changes:51897
From: normal <ko1@a...>
Date: Mon, 30 Jul 2018 11:28:05 +0900 (JST)
Subject: [ruby-changes:51897] normal:r64111 (trunk): thread_pthread.c (rb_sigwait_sleep): re-fix [Bug #5343] harder
normal 2018-07-30 11:28:00 +0900 (Mon, 30 Jul 2018) New Revision: 64111 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64111 Log: 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] Modified files: trunk/thread.c trunk/thread_pthread.c Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 64110) +++ thread_pthread.c (revision 64111) @@ -1613,11 +1613,45 @@ rb_sigwait_sleep(rb_thread_t *th, int si https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1613 { 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; - (void)ppoll(&pfd, 1, ts, 0); - check_signals_nogvl(th, sigwait_fd); + 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; + } + + 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 Index: thread.c =================================================================== --- thread.c (revision 64110) +++ thread.c (revision 64111) @@ -106,6 +106,7 @@ static int rb_threadptr_pending_interrup https://github.com/ruby/ruby/blob/trunk/thread.c#L106 static const char *thread_status_name(rb_thread_t *th, int detail); static void timespec_add(struct timespec *, const struct timespec *); static void timespec_sub(struct timespec *, const struct timespec *); +static int timespec_cmp(const struct timespec *a, const struct timespec *b); static int timespec_update_expire(struct timespec *, const struct timespec *); static void getclockofday(struct timespec *); NORETURN(static void async_bug_fd(const char *mesg, int errno_arg, int fd)); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/