From: nobu.nokada@... Date: 2002-05-09T23:38:45+09:00 Subject: Re: Thread#join doesn't accept a timeout? Hi, At Thu, 9 May 2002 21:55:06 +0900, Dossy wrote: > On 2002.05.09, Jean-Hugues ROBERT wrote: > > > > I guess timeout should be in seconds, as in sleep(), shouldn't it ? > > On 2002.05.09, nobu.nokada@softhome.net wrote: > > Agreed. And also in IO.select. > > But, it still gives millisecond precision, right? Yes, with Float. > > # I'd posted a patch implemented it to ruby-core, but failed. > > Wow, that was fast! :-) > > Of course, since I'm using stable (both on mswin32 and linux) > I won't see this new change for a while, huh? Perhaps, unless you apply the patch by yourself. However, it seems possible to apply to the stable. Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.291 diff -u -2 -p -r1.291 eval.c --- eval.c 2002/05/07 06:28:06 1.291 +++ eval.c 2002/05/09 09:26:41 @@ -8089,9 +8089,11 @@ rb_thread_select(max, read, write, excep } -static VALUE -rb_thread_join(thread) - VALUE thread; +static int rb_thread_join _((rb_thread_t, double)); + +static int +rb_thread_join(th, limit) + rb_thread_t th; + double limit; { - rb_thread_t th = rb_thread_check(thread); enum thread_status last_status = THREAD_RUNNABLE; @@ -8104,9 +8106,13 @@ rb_thread_join(thread) if (curr_thread->status == THREAD_TO_KILL) last_status = THREAD_TO_KILL; + if (limit == 0) return Qfalse; curr_thread->status = THREAD_STOPPED; curr_thread->join = th; curr_thread->wait_for = WAIT_JOIN; + curr_thread->delay = timeofday() + limit; + if (limit < DELAY_INFTY) curr_thread->wait_for |= WAIT_TIME; rb_thread_schedule(); curr_thread->status = last_status; + if (!rb_thread_dead(th)) return Qfalse; } @@ -8122,4 +8128,20 @@ rb_thread_join(thread) } + return Qtrue; +} + +static VALUE +rb_thread_join_m(argc, argv, thread) + int argc; + VALUE *argv; +{ + VALUE limit; + double delay = DELAY_INFTY; + rb_thread_t th = rb_thread_check(thread); + + rb_scan_args(argc, argv, "01", &limit); + if (!NIL_P(limit)) delay = rb_num2dbl(limit); + if (!rb_thread_join(th, delay)) + return Qnil; return thread; } @@ -8642,5 +8664,5 @@ rb_thread_value(thread) rb_thread_t th = rb_thread_check(thread); - rb_thread_join(thread); + while (!rb_thread_join(th, DELAY_INFTY)); return th->result; @@ -9136,5 +9158,5 @@ Init_Thread() rb_define_method(rb_cThread, "value", rb_thread_value, 0); rb_define_method(rb_cThread, "status", rb_thread_status, 0); - rb_define_method(rb_cThread, "join", rb_thread_join, 0); + rb_define_method(rb_cThread, "join", rb_thread_join_m, -1); rb_define_method(rb_cThread, "alive?", rb_thread_alive_p, 0); rb_define_method(rb_cThread, "stop?", rb_thread_stop_p, 0); -- Nobu Nakada