[前][次][番号順一覧][スレッド一覧]

ruby-changes:50347

From: normal <ko1@a...>
Date: Sun, 18 Feb 2018 12:00:37 +0900 (JST)
Subject: [ruby-changes:50347] normal:r62462 (trunk): thread.c (thread_join_m): handle negative timeouts correctly

normal	2018-02-18 12:00:33 +0900 (Sun, 18 Feb 2018)

  New Revision: 62462

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62462

  Log:
    thread.c (thread_join_m): handle negative timeouts correctly
    
    Users may subtract and round into negative values when using
    Thread#join, so clamp the timeout to zero to avoid infinite/long
    timeouts.
    
    Note: other methods such as Kernel#sleep and IO.select will
    raise on negative values, but Thread#join is an outlier *shrug*
    
    This restores Ruby 2.5 (and earlier) behavior.
    
    Fixes: r62182 (commit c915390b9530c31b4665aacf27c1adfc114f768e)
           ("thread.c: avoid FP for Thread#join")

  Modified files:
    trunk/test/ruby/test_thread.rb
    trunk/thread.c
Index: test/ruby/test_thread.rb
===================================================================
--- test/ruby/test_thread.rb	(revision 62461)
+++ test/ruby/test_thread.rb	(revision 62462)
@@ -234,6 +234,13 @@ class TestThread < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L234
       t = Thread.new {}
       assert_same t, t.join(limit), "limit=#{limit.inspect}"
     end
+    t = Thread.new { sleep }
+    [ -1, -0.1, RbConfig::LIMITS['FIXNUM_MIN'], RbConfig::LIMITS['INT64_MIN'],
+      -Float::INFINITY
+    ].each do |limit|
+      assert_nil t.join(limit), "limit=#{limit.inspect}"
+    end
+    t.kill
   end
 
   def test_kill_main_thread
Index: thread.c
===================================================================
--- thread.c	(revision 62461)
+++ thread.c	(revision 62462)
@@ -1061,6 +1061,8 @@ thread_join_m(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/thread.c#L1061
       case T_NIL: break;
       case T_FIXNUM:
         timespec.tv_sec = NUM2TIMET(limit);
+        if (timespec.tv_sec < 0)
+            timespec.tv_sec = 0;
         timespec.tv_nsec = 0;
         ts = &timespec;
         break;
@@ -1116,8 +1118,8 @@ double2timespec(struct timespec *ts, dou https://github.com/ruby/ruby/blob/trunk/thread.c#L1118
     if (TIMESPEC_SEC_MAX_PLUS_ONE <= d) {
         return NULL;
     }
-    else if (d <= TIMESPEC_SEC_MIN) {
-        ts->tv_sec = TIMESPEC_SEC_MIN;
+    else if (d <= 0) {
+        ts->tv_sec = 0;
         ts->tv_nsec = 0;
     }
     else {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]