* thread_{pthread,win32}.c (native_sleep): wait until timed out.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17972 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2008-07-09 11:35:06 +00:00
parent a2ec2f8b59
commit 7df7982b47
3 changed files with 40 additions and 5 deletions

View File

@ -1,3 +1,7 @@
Wed Jul 9 20:35:03 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* thread_{pthread,win32}.c (native_sleep): wait until timed out.
Wed Jul 9 20:18:50 2008 Nobuyoshi Nakada <nobu@ruby-lang.org> Wed Jul 9 20:18:50 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* configure.in (rb_cv_va_args_macro): check for __VA_ARGS__. * configure.in (rb_cv_va_args_macro): check for __VA_ARGS__.

View File

@ -496,6 +496,7 @@ static void
native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable) native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
{ {
int prev_status = th->status; int prev_status = th->status;
int retry = 0;
struct timespec ts; struct timespec ts;
struct timeval tvn; struct timeval tvn;
@ -519,6 +520,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
} }
thread_debug("native_sleep %ld\n", tv ? tv->tv_sec : -1); thread_debug("native_sleep %ld\n", tv ? tv->tv_sec : -1);
sleep_again:
GVL_UNLOCK_BEGIN(); GVL_UNLOCK_BEGIN();
{ {
pthread_mutex_lock(&th->interrupt_lock); pthread_mutex_lock(&th->interrupt_lock);
@ -530,7 +532,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
thread_debug("native_sleep: interrupted before sleep\n"); thread_debug("native_sleep: interrupted before sleep\n");
} }
else { else {
if (tv == 0 || ts.tv_sec < tvn.tv_sec /* overflow */ ) { if (tv == 0 || (!retry && ts.tv_sec < tvn.tv_sec /* overflow */)) {
int r; int r;
thread_debug("native_sleep: pthread_cond_wait start\n"); thread_debug("native_sleep: pthread_cond_wait start\n");
r = pthread_cond_wait(&th->native_thread_data.sleep_cond, r = pthread_cond_wait(&th->native_thread_data.sleep_cond,
@ -540,7 +542,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
} }
else { else {
int r; int r;
thread_debug("native_sleep: pthread_cond_timedwait start (%ld, %ld)\n", thread_debug("native_sleep: pthread_cond_timedwait start (%ld.%.9ld)\n",
(unsigned long)ts.tv_sec, ts.tv_nsec); (unsigned long)ts.tv_sec, ts.tv_nsec);
r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond,
&th->interrupt_lock, &ts); &th->interrupt_lock, &ts);
@ -558,6 +560,17 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
th->status = prev_status; th->status = prev_status;
if (!tv && deadlockable) th->vm->sleeper--; if (!tv && deadlockable) th->vm->sleeper--;
RUBY_VM_CHECK_INTS(); RUBY_VM_CHECK_INTS();
if (tv) {
gettimeofday(&tvn, NULL);
if (ts.tv_sec > tvn.tv_sec ||
(ts.tv_sec == tvn.tv_sec && ts.tv_nsec > tvn.tv_usec * 1000)) {
thread_debug("native_sleep: %ld.%.9ld > %ld.%.6ld\n",
(long)ts.tv_sec, ts.tv_nsec,
(long)tvn.tv_sec, tvn.tv_usec);
retry = 1;
goto sleep_again;
}
}
thread_debug("native_sleep done\n"); thread_debug("native_sleep done\n");
} }

View File

@ -207,9 +207,17 @@ static void
native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable) native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
{ {
int prev_status = th->status; int prev_status = th->status;
DWORD msec; int retry = 0;
DWORD msec, ret;
struct timeval tvn, limit;
if (tv) { if (tv) {
gettimeofday(&limit, NULL);
limit.tv_sec += tv->tv_sec;
if ((limit.tv_usec += tv->tv_usec) >= 1000000) {
limit.tv_sec += limit.tv_usec / 1000000;
limit.tv_usec %= 1000000;
}
msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
} }
else { else {
@ -225,10 +233,9 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
th->status = THREAD_STOPPED; th->status = THREAD_STOPPED;
} }
sleep_again:
GVL_UNLOCK_BEGIN(); GVL_UNLOCK_BEGIN();
{ {
DWORD ret;
native_mutex_lock(&th->interrupt_lock); native_mutex_lock(&th->interrupt_lock);
th->unblock.func = ubf_handle; th->unblock.func = ubf_handle;
th->unblock.arg = th; th->unblock.arg = th;
@ -252,6 +259,17 @@ native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable)
th->status = prev_status; th->status = prev_status;
if (!tv && deadlockable) th->vm->sleeper--; if (!tv && deadlockable) th->vm->sleeper--;
RUBY_VM_CHECK_INTS(); RUBY_VM_CHECK_INTS();
if (tv) {
gettimeofday(&tvn, NULL);
if (limit.tv_sec > tvn.tv_sec ||
(limit.tv_sec == tvn.tv_sec && limit.tv_usec > tvn.tv_usec)) {
thread_debug("native_sleep: %ld.%.6ld > %ld.%.6ld\n",
(long)limit.tv_sec, limit.tv_usec,
(long)tvn.tv_sec, tvn.tv_usec);
retry = 1;
goto sleep_again;
}
}
} }
static int static int