summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
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