1
0
Fork 0
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:
Nobuyoshi Nakada 2021-10-03 20:03:24 +09:00
parent 853ca5cceb
commit 19f9d9cf73
Notes: git 2021-10-03 22:06:51 +09:00
2 changed files with 22 additions and 21 deletions

View file

@ -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

View file

@ -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;
}