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

ruby-changes:52254

From: normal <ko1@a...>
Date: Sun, 19 Aug 2018 05:04:11 +0900 (JST)
Subject: [ruby-changes:52254] normal:r64464 (trunk): thread_sync.c (rb_mutex_sleep): skip interrupt check before sleep

normal	2018-08-19 05:04:07 +0900 (Sun, 19 Aug 2018)

  New Revision: 64464

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

  Log:
    thread_sync.c (rb_mutex_sleep): skip interrupt check before sleep
    
    We do not want to risk switching threads before going to sleep
    because it can cause unexpected wakeups and put us in an
    unexpected state when used with ConditionVariable.

  Modified files:
    trunk/thread.c
    trunk/thread_sync.c
Index: thread_sync.c
===================================================================
--- thread_sync.c	(revision 64463)
+++ thread_sync.c	(revision 64464)
@@ -438,7 +438,7 @@ rb_mutex_cleanup_keeping_mutexes(const r https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L438
 static VALUE
 rb_mutex_sleep_forever(VALUE time)
 {
-    rb_thread_sleep_deadly_allow_spurious_wakeup();
+    sleep_forever(GET_THREAD(), SLEEP_DEADLOCKABLE|SLEEP_BEFORE_CHECK_INTS);
     return Qnil;
 }
 
@@ -446,7 +446,8 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/thread_sync.c#L446
 rb_mutex_wait_for(VALUE time)
 {
     struct timespec *t = (struct timespec*)time;
-    sleep_timespec(GET_THREAD(), *t, 0); /* permit spurious check */
+    /* permit spurious check */
+    sleep_timespec(GET_THREAD(), *t, SLEEP_BEFORE_CHECK_INTS);
     return Qnil;
 }
 
Index: thread.c
===================================================================
--- thread.c	(revision 64463)
+++ thread.c	(revision 64464)
@@ -94,7 +94,8 @@ static ID id_locals; https://github.com/ruby/ruby/blob/trunk/thread.c#L94
 
 enum SLEEP_FLAGS {
     SLEEP_DEADLOCKABLE = 0x1,
-    SLEEP_SPURIOUS_CHECK = 0x2
+    SLEEP_SPURIOUS_CHECK = 0x2,
+    SLEEP_BEFORE_CHECK_INTS = 0x4
 };
 
 static void sleep_timespec(rb_thread_t *, struct timespec, unsigned int fl);
@@ -1187,7 +1188,9 @@ sleep_forever(rb_thread_t *th, unsigned https://github.com/ruby/ruby/blob/trunk/thread.c#L1188
 
     status  = fl & SLEEP_DEADLOCKABLE ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
     th->status = status;
-    RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+    if (!(fl & SLEEP_BEFORE_CHECK_INTS)) {
+        RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+    }
     while (th->status == status) {
 	if (fl & SLEEP_DEADLOCKABLE) {
 	    th->vm->sleeper++;
@@ -1293,7 +1296,9 @@ sleep_timespec(rb_thread_t *th, struct t https://github.com/ruby/ruby/blob/trunk/thread.c#L1296
     getclockofday(&end);
     timespec_add(&end, &ts);
     th->status = THREAD_STOPPED;
-    RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+    if (!(fl & SLEEP_BEFORE_CHECK_INTS)) {
+        RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+    }
     while (th->status == THREAD_STOPPED) {
 	native_sleep(th, &ts);
 	woke = vm_check_ints_blocking(th->ec);

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

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