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
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 const char *thread_status_name(rb_thread_t *th, int detail);
|
||||||
static void timespec_add(struct timespec *, const struct timespec *);
|
static void timespec_add(struct timespec *, const struct timespec *);
|
||||||
static void timespec_sub(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 int timespec_update_expire(struct timespec *, const struct timespec *);
|
||||||
static void getclockofday(struct timespec *);
|
static void getclockofday(struct timespec *);
|
||||||
NORETURN(static void async_bug_fd(const char *mesg, int errno_arg, int fd));
|
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;
|
struct pollfd pfd;
|
||||||
|
|
||||||
pfd.fd = sigwait_fd;
|
if (ubf_threads_empty()) {
|
||||||
pfd.events = POLLIN;
|
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);
|
if (ts) {
|
||||||
check_signals_nogvl(th, sigwait_fd);
|
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
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user