mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Remove extraneous conversion to float [Bug #18236]
This commit is contained in:
parent
853ca5cceb
commit
19f9d9cf73
Notes:
git
2021-10-03 22:06:51 +09:00
2 changed files with 22 additions and 21 deletions
|
@ -235,6 +235,14 @@ class TestThread < Test::Unit::TestCase
|
|||
t3&.kill&.join
|
||||
end
|
||||
|
||||
def test_join_argument_conversion
|
||||
t = Thread.new {}
|
||||
assert_raise(TypeError) {t.join(:foo)}
|
||||
|
||||
limit = Struct.new(:to_f, :count).new(0.05)
|
||||
assert_same(t, t.join(limit))
|
||||
end
|
||||
|
||||
{ 'FIXNUM_MAX' => RbConfig::LIMITS['FIXNUM_MAX'],
|
||||
'UINT64_MAX' => RbConfig::LIMITS['UINT64_MAX'],
|
||||
'INFINITY' => Float::INFINITY
|
||||
|
|
35
thread.c
35
thread.c
|
@ -1137,6 +1137,7 @@ struct join_arg {
|
|||
struct rb_waiting_list *waiter;
|
||||
rb_thread_t *target;
|
||||
VALUE timeout;
|
||||
rb_hrtime_t *limit;
|
||||
};
|
||||
|
||||
static VALUE
|
||||
|
@ -1174,22 +1175,7 @@ thread_join_sleep(VALUE arg)
|
|||
{
|
||||
struct join_arg *p = (struct join_arg *)arg;
|
||||
rb_thread_t *target_th = p->target, *th = p->waiter->thread;
|
||||
rb_hrtime_t end = 0, rel = 0, *limit = 0;
|
||||
|
||||
/*
|
||||
* This supports INFINITY and negative values, so we can't use
|
||||
* rb_time_interval right now...
|
||||
*/
|
||||
if (p->timeout == Qnil) {
|
||||
/* unlimited */
|
||||
}
|
||||
else if (FIXNUM_P(p->timeout)) {
|
||||
rel = rb_sec2hrtime(NUM2TIMET(p->timeout));
|
||||
limit = &rel;
|
||||
}
|
||||
else {
|
||||
limit = double2hrtime(&rel, rb_num2dbl(p->timeout));
|
||||
}
|
||||
rb_hrtime_t end = 0, *limit = p->limit;
|
||||
|
||||
if (limit) {
|
||||
end = rb_hrtime_add(*limit, rb_hrtime_now());
|
||||
|
@ -1226,7 +1212,7 @@ thread_join_sleep(VALUE arg)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
thread_join(rb_thread_t *target_th, VALUE timeout)
|
||||
thread_join(rb_thread_t *target_th, VALUE timeout, rb_hrtime_t *limit)
|
||||
{
|
||||
rb_execution_context_t *ec = GET_EC();
|
||||
rb_thread_t *th = ec->thread_ptr;
|
||||
|
@ -1254,6 +1240,7 @@ thread_join(rb_thread_t *target_th, VALUE timeout)
|
|||
arg.waiter = &waiter;
|
||||
arg.target = target_th;
|
||||
arg.timeout = timeout;
|
||||
arg.limit = limit;
|
||||
|
||||
if (!rb_ensure(thread_join_sleep, (VALUE)&arg, remove_from_join_list, (VALUE)&arg)) {
|
||||
return Qnil;
|
||||
|
@ -1332,23 +1319,29 @@ static VALUE
|
|||
thread_join_m(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE timeout = Qnil;
|
||||
rb_hrtime_t rel = 0, *limit = 0;
|
||||
|
||||
if (rb_check_arity(argc, 0, 1)) {
|
||||
timeout = argv[0];
|
||||
}
|
||||
|
||||
// Convert the timeout eagerly, so it's always converted and deterministic
|
||||
/*
|
||||
* This supports INFINITY and negative values, so we can't use
|
||||
* rb_time_interval right now...
|
||||
*/
|
||||
if (timeout == Qnil) {
|
||||
/* unlimited */
|
||||
}
|
||||
else if (FIXNUM_P(timeout)) {
|
||||
/* handled directly in thread_join_sleep() */
|
||||
rel = rb_sec2hrtime(NUM2TIMET(timeout));
|
||||
limit = &rel;
|
||||
}
|
||||
else {
|
||||
timeout = rb_to_float(timeout);
|
||||
limit = double2hrtime(&rel, rb_num2dbl(timeout));
|
||||
}
|
||||
|
||||
return thread_join(rb_thread_ptr(self), timeout);
|
||||
return thread_join(rb_thread_ptr(self), timeout, limit);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1369,7 +1362,7 @@ static VALUE
|
|||
thread_value(VALUE self)
|
||||
{
|
||||
rb_thread_t *th = rb_thread_ptr(self);
|
||||
thread_join(th, Qnil);
|
||||
thread_join(th, Qnil, 0);
|
||||
return th->value;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue