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 <mame / tsg.ne.jp>
----------------------------------------
http://redmine.ruby-lang.org/issues/show/1341

----------------------------------------
http://redmine.ruby-lang.org