summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-09 13:41:19 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-07-09 13:41:19 +0000
commita14682906f063617ce22969dd100a512fe63ba33 (patch)
treeb27897d65ee8f8da1987de36125d64842dfecc06 /thread.c
parent6372357ad51ccbf909d36c6516229d3be0f30043 (diff)
* thread.c (sleep_forever): wait until timed out. [ruby-core:17270]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/thread.c b/thread.c
index d0787b20a2..50748a8e14 100644
--- a/thread.c
+++ b/thread.c
@@ -718,9 +718,47 @@ sleep_forever(rb_thread_t *th, int deadlockable)
}
static void
+getclockofday(struct timeval *tp)
+{
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / 1000;
+ } else
+#endif
+ {
+ gettimeofday(tp, NULL);
+ }
+}
+
+static void
sleep_timeval(rb_thread_t *th, struct timeval tv)
{
- native_sleep(th, &tv, 0);
+ struct timeval to, tvn;
+
+ getclockofday(&to);
+ to.tv_sec += tv.tv_sec;
+ if ((to.tv_usec += tv.tv_usec) >= 1000000) {
+ to.tv_sec++;
+ to.tv_usec -= 1000000;
+ }
+
+ for (;;) {
+ native_sleep(th, &tv, 0);
+ getclockofday(&tvn);
+ if (to.tv_sec < tvn.tv_sec) break;
+ if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break;
+ thread_debug("sleep_timeval: %ld.%.6ld > %ld.%.6ld\n",
+ (long)to.tv_sec, to.tv_usec,
+ (long)tvn.tv_sec, tvn.tv_usec);
+ tv.tv_sec = to.tv_sec - tvn.tv_sec;
+ if ((tv.tv_usec = to.tv_usec - tvn.tv_usec) < 0) {
+ --tv.tv_sec;
+ tv.tv_usec += 1000000;
+ }
+ }
}
void