From: Yusuke ENDOH Date: 2010-05-06T09:23:33+09:00 Subject: [ruby-core:30040] Re: [Bug #1341] pthread_cond_timedwait failing in 1.9.1-p0 thread tests Hi, 2010/5/6 Graham Agnew : > On HP-UX, that patch stopped the rb_bug_errno happening, although the test/ruby/test_io.rb and test/ruby/test_thread.rb scripts both blocked indefinitely. > > The code in your patch doesn't look right to me. ?Shouldn't the code re-fetch the time using gettimeofday each time through the loop, and then add the MEGA_SEC to that? ?As it is, it's wrong because it adds a MEGA_SEC to tvn, so after one MEGA_SEC it will enter a hard loop. Thank you for your testing! How about the following patch? To tell the truth, I'm writing a patch without test because I don't have HP-UX. If this is wrong again, It is really helpful for you to correct the patch by yourself. diff --git a/thread_pthread.c b/thread_pthread.c index e6295db..3c13f72 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -631,8 +631,29 @@ native_sleep(rb_thread_t *th, struct timeval *tv) int r; thread_debug("native_sleep: pthread_cond_timedwait start (%ld, %ld)\n", (unsigned long)ts.tv_sec, ts.tv_nsec); + again: 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 timespec lts; + r = ETIMEDOUT; + while (r == ETIMEDOUT) { + gettimeofday(&tvn, NULL); + lts.tv_sec = tvn.tv_sec + MEGA_SEC; + lts.tv_nsec = tvn.tv_usec * 1000; + if (lts.tv_sec >= ts.tv_sec) goto again; + r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, + &th->interrupt_lock, <s); + if (r && r != ETIMEDOUT) rb_bug_errno("pthread_cond_timedwait", r); + } + } if (r && r != ETIMEDOUT) rb_bug_errno("pthread_cond_timedwait", r); thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r); -- Yusuke Endoh