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

ruby-changes:49184

From: normal <ko1@a...>
Date: Sun, 17 Dec 2017 17:26:22 +0900 (JST)
Subject: [ruby-changes:49184] normal:r61302 (trunk): thread.c: fix overly long Thread#join w/ timeout

normal	2017-12-17 17:26:17 +0900 (Sun, 17 Dec 2017)

  New Revision: 61302

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

  Log:
    thread.c: fix overly long Thread#join w/ timeout
    
    * test/ruby/test_thread.rb (test_signal_at_join): test with timeout
    * thread.c (sleep_wait_for_interrupt): remove
      (thread_join_sleep): use native_sleep directly to avoid extra
      missing thread status change
      [Bug #14181]

  Modified files:
    trunk/test/ruby/test_thread.rb
    trunk/thread.c
Index: test/ruby/test_thread.rb
===================================================================
--- test/ruby/test_thread.rb	(revision 61301)
+++ test/ruby/test_thread.rb	(revision 61302)
@@ -1284,6 +1284,20 @@ q.pop https://github.com/ruby/ruby/blob/trunk/test/ruby/test_thread.rb#L1284
             end
           end
         end
+        n.times do
+          w = Thread.start { sleep 30 }
+          begin
+            f.puts
+            f.gets
+          ensure
+            w.kill
+            t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+            w.join(30)
+            t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+            diff = t1 - t0
+            assert_operator diff, :<=, 2
+          end
+        end
       end
     };
   end
Index: thread.c
===================================================================
--- thread.c	(revision 61301)
+++ thread.c	(revision 61302)
@@ -91,7 +91,6 @@ static VALUE sym_never; https://github.com/ruby/ruby/blob/trunk/thread.c#L91
 static ID id_locals;
 
 static void sleep_timeval(rb_thread_t *th, struct timeval time, int spurious_check);
-static void sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec, int spurious_check);
 static void sleep_forever(rb_thread_t *th, int nodeadlock, int spurious_check);
 static void rb_thread_sleep_deadly_allow_spurious_wakeup(void);
 static double timeofday(void);
@@ -888,18 +887,22 @@ thread_join_sleep(VALUE arg) https://github.com/ruby/ruby/blob/trunk/thread.c#L887
 	    rb_check_deadlock(th->vm);
 	    native_sleep(th, 0);
 	    th->vm->sleeper--;
-	    RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
-	    th->status = THREAD_RUNNABLE;
 	}
 	else {
 	    double now = timeofday();
+	    struct timeval tv;
+
 	    if (now > limit) {
 		thread_debug("thread_join: timeout (thid: %"PRI_THREAD_ID")\n",
 			     thread_id_str(target_th));
 		return Qfalse;
 	    }
-	    sleep_wait_for_interrupt(th, limit - now, 0);
+	    tv = double2timeval(limit - now);
+	    th->status = THREAD_STOPPED;
+	    native_sleep(th, &tv);
 	}
+	RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+	th->status = THREAD_RUNNABLE;
 	thread_debug("thread_join: interrupted (thid: %"PRI_THREAD_ID", status: %s)\n",
 		     thread_id_str(target_th), thread_status_name(target_th, TRUE));
     }
@@ -1231,12 +1234,6 @@ timeofday(void) https://github.com/ruby/ruby/blob/trunk/thread.c#L1234
     }
 }
 
-static void
-sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec, int spurious_check)
-{
-    sleep_timeval(th, double2timeval(sleepsec), spurious_check);
-}
-
 void
 rb_thread_wait_for(struct timeval time)
 {

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

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