Project

General

Profile

Feature #5958 ยป patch.diff

Glass_saga (Masaki Matsushita), 02/01/2012 11:19 PM

View differences:

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);
    (1-1/1)