Feature #5958 ยป patch.diff
test/ruby/test_thread.rb | ||
---|---|---|
end
|
||
assert_in_delta(t1 - t0, 1, 1)
|
||
end
|
||
def test_join
|
||
thgrp = ThreadGroup.new
|
||
thgrp.add(t = Thread.new{ sleep })
|
||
t0 = Time.now.to_f
|
||
assert_nil(thgrp.join(1))
|
||
t1 = Time.now.to_f
|
||
assert_in_delta(t1 - t0, 1, 1)
|
||
ensure
|
||
t.kill if t
|
||
end
|
||
end
|
thread.c | ||
---|---|---|
return ary;
|
||
}
|
||
struct thgroup_join_params {
|
||
double limit;
|
||
VALUE group;
|
||
};
|
||
static int
|
||
thgroup_join_i(st_data_t key, st_data_t value, st_data_t data)
|
||
{
|
||
VALUE thread = (VALUE)key;
|
||
rb_thread_t *th;
|
||
struct thgroup_join_params *args = (struct thgroup_join_params *)data;
|
||
double delay = args->limit;
|
||
GetThreadPtr(thread, th);
|
||
if (th->thgroup == args->group) {
|
||
if (delay != DELAY_INFTY) delay -= timeofday();
|
||
if (NIL_P(thread_join(th, delay))) {
|
||
args->group = Qnil;
|
||
return ST_STOP;
|
||
}
|
||
}
|
||
return ST_CONTINUE;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* thgrp.join -> thgrp
|
||
* thgrp.join(limit) -> thgrp or nil
|
||
*
|
||
* The calling thread will suspend execution until threads in the receiving
|
||
* <code>ThreadGroup</code> exit or until <i>limit</i> seconds have passed.
|
||
* If the time limit expires, <code>nil</code> will be returned, otherwise
|
||
* <i>thgrp</i> is returned.
|
||
*
|
||
*/
|
||
static VALUE
|
||
thgroup_join(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
VALUE limit;
|
||
struct thgroup_join_params param;
|
||
rb_scan_args(argc, argv, "01", &limit);
|
||
if (!NIL_P(limit)) {
|
||
param.limit = timeofday() + rb_num2dbl(limit);
|
||
} else {
|
||
param.limit = DELAY_INFTY;
|
||
}
|
||
param.group = self;
|
||
st_foreach(GET_THREAD()->vm->living_threads, thgroup_join_i, (st_data_t) & param);
|
||
return param.group;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
... | ... | |
rb_define_method(cThGroup, "enclose", thgroup_enclose, 0);
|
||
rb_define_method(cThGroup, "enclosed?", thgroup_enclosed_p, 0);
|
||
rb_define_method(cThGroup, "add", thgroup_add, 1);
|
||
rb_define_method(cThGroup, "join", thgroup_join, -1);
|
||
{
|
||
th->thgroup = th->vm->thgroup_default = rb_obj_alloc(cThGroup);
|