summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <[email protected]>2021-10-03 20:03:24 +0900
committerNobuyoshi Nakada <[email protected]>2021-10-03 22:06:31 +0900
commit19f9d9cf739e7fc185ef90d5da5b4b12cf902a52 (patch)
treee393ab73b3b2ec6d8569f6ee933fbd5bc3c57f93
parent853ca5ccebc71f3eb2235e8847f3b20a949943a2 (diff)
Remove extraneous conversion to float [Bug #18236]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4927
-rw-r--r--test/ruby/test_thread.rb8
-rw-r--r--thread.c35
2 files changed, 22 insertions, 21 deletions
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index 19a3529005..7b37aeb202 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -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
diff --git a/thread.c b/thread.c
index 148a43aed9..55d8ca671e 100644
--- a/thread.c
+++ b/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;
}