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:
parent
3dc7727d22
commit
26b8a70bb3
2 changed files with 39 additions and 4 deletions
1
thread.c
1
thread.c
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue