1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
normal 2018-07-30 02:28:00 +00:00
parent 3dc7727d22
commit 26b8a70bb3
2 changed files with 39 additions and 4 deletions

View file

@ -106,6 +106,7 @@ static int rb_threadptr_pending_interrupt_empty_p(const rb_thread_t *th);
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));

View file

@ -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;
(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