From: Yusuke Endoh Date: 2010-04-22T02:31:35+09:00 Subject: [ruby-core:29702] [Bug #1341] pthread_cond_timedwait failing in 1.9.1-p0 thread tests Issue #1341 has been updated by Yusuke Endoh. Assigned to set to Yusuke Endoh Hi, I guess this is the limitation of Solaris: - http://bugs.opensolaris.org/view_bug.do?bug_id=4038480 - http://docs.sun.com/app/docs/doc/806-0630/6j9vkb8ct?a=view EINVAL ... For cond_timedwait(), the specified number of seconds, abstime, is greater than current_time + 100,000,000, where current_time is the current time, or the number of nanoseconds is greater than or equal to 1,000,000,000. Maybe, HP-UX has the same limitation, though I cannot find the evidence. I wrote a workaround patch: diff --git a/thread_pthread.c b/thread_pthread.c index e6295db..7387724 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -633,6 +633,35 @@ native_sleep(rb_thread_t *th, struct timeval *tv) (unsigned long)ts.tv_sec, ts.tv_nsec); r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, &th->interrupt_lock, &ts); + if (r == EINVAL) { + /* workaround for Solaris: wait by MEGA_SEC's. + * on Solaris, pthread_cond_timedwait fails with EINVAL + * if time is too far from now. [Bug #1341] + * - http://docs.sun.com/app/docs/doc/806-0630/6j9vkb8ct?a=view + * - http://bugs.opensolaris.org/view_bug.do?bug_id=4038480 + */ +#define MEGA_SEC 1000000 + struct timeval ltv = *tv; + r = ETIMEDOUT; + while (r == ETIMEDOUT && ltv.tv_sec > MEGA_SEC) { + ts.tv_sec = tvn.tv_sec + MEGA_SEC; + ts.tv_nsec = tvn.tv_usec * 1000; + ltv.tv_sec -= MEGA_SEC; + r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, + &th->interrupt_lock, &ts); + if (r && r != ETIMEDOUT) rb_bug_errno("pthread_cond_timedwait", r); + } + if (r == ETIMEDOUT) { + ts.tv_sec = tvn.tv_sec + ltv.tv_sec; + ts.tv_nsec = (tvn.tv_usec + ltv.tv_usec) * 1000; + if (ts.tv_nsec >= PER_NANO){ + ts.tv_sec += 1; + ts.tv_nsec -= PER_NANO; + } + r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, + &th->interrupt_lock, &ts); + } + } if (r && r != ETIMEDOUT) rb_bug_errno("pthread_cond_timedwait", r); thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r); -- Yusuke Endoh ---------------------------------------- http://redmine.ruby-lang.org/issues/show/1341 ---------------------------------------- http://redmine.ruby-lang.org