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

ruby-changes:23891

From: shyouhei <ko1@a...>
Date: Wed, 6 Jun 2012 15:16:37 +0900 (JST)
Subject: [ruby-changes:23891] shyouhei:r35942 (ruby_1_8_7): merge revision(s) 23432:

shyouhei	2012-06-06 15:16:25 +0900 (Wed, 06 Jun 2012)

  New Revision: 35942

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35942

  Log:
    merge revision(s) 23432:
    * eval.c (rb_thread_join), ext/thread/thread.c (wake_one): adjusts
      targets of rest waiting threads to join.  [ruby-core:23457]

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/eval.c
    branches/ruby_1_8_7/ext/thread/thread.c
    branches/ruby_1_8_7/test/thread/test_thread.rb
    branches/ruby_1_8_7/version.h

Index: ruby_1_8_7/ext/thread/thread.c
===================================================================
--- ruby_1_8_7/ext/thread/thread.c	(revision 35941)
+++ ruby_1_8_7/ext/thread/thread.c	(revision 35942)
@@ -205,6 +205,16 @@
     return ary;
 }
 
+static void
+adjust_join(const List *list, VALUE new)
+{
+    extern void rb_thread_set_join _((VALUE, VALUE));
+    Entry *entry;
+    for (entry = list->entries; entry; entry = entry->next) {
+	rb_thread_set_join(entry->value, new);
+    }
+}
+
 static VALUE
 wake_thread(VALUE thread)
 {
@@ -221,7 +231,7 @@
 }
 
 static VALUE
-wake_one(List *list)
+wake_first(List *list)
 {
     VALUE waking;
 
@@ -234,10 +244,22 @@
 }
 
 static VALUE
+wake_one(List *list)
+{
+    VALUE waking = wake_first(list);
+
+    if (!NIL_P(waking)) {
+	adjust_join(list, waking);
+    }
+
+    return waking;
+}
+
+static VALUE
 wake_all(List *list)
 {
     while (list->entries) {
-        wake_one(list);
+        wake_first(list);
     }
     return Qnil;
 }
Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 35941)
+++ ruby_1_8_7/ChangeLog	(revision 35942)
@@ -1,3 +1,8 @@
+Wed Jun  6 15:09:00 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* eval.c (rb_thread_join), ext/thread/thread.c (wake_one): adjusts
+	  targets of rest waiting threads to join.  [ruby-core:23457]
+
 Wed Jun  6 14:44:13 2012  Kenta Murata  <mrkn@m...>
 
 	* bignum.c (rb_big2dbl), test/ruby/test_bignum.rb (test_to_f):
Index: ruby_1_8_7/version.h
===================================================================
--- ruby_1_8_7/version.h	(revision 35941)
+++ ruby_1_8_7/version.h	(revision 35942)
@@ -2,7 +2,7 @@
 #define RUBY_RELEASE_DATE "2012-06-06"
 #define RUBY_VERSION_CODE 187
 #define RUBY_RELEASE_CODE 20120606
-#define RUBY_PATCHLEVEL 365
+#define RUBY_PATCHLEVEL 366
 
 #define RUBY_VERSION_MAJOR 1
 #define RUBY_VERSION_MINOR 8
Index: ruby_1_8_7/test/thread/test_thread.rb
===================================================================
--- ruby_1_8_7/test/thread/test_thread.rb	(revision 35941)
+++ ruby_1_8_7/test/thread/test_thread.rb	(revision 35942)
@@ -86,5 +86,68 @@
         assert_nothing_raised("[ruby-dev:37545]") {assert_equal(1, queue.pop)}
         assert(queue.empty?)
     end
+
+  # This test checks that a thread in Mutex#lock which is raised is
+  # completely removed from the wait_list of the mutex
+  def test_mutex_exception_handling
+    m = Mutex.new
+    m.lock
+
+    sleeping = false
+    t = Thread.new do
+      begin
+        m.lock
+      rescue
+      end
+
+      sleeping = true
+      # Keep that thread alive: if the thread returns, the test method
+      # won't be able to check that +m+ has not been taken (dead mutex
+      # owners are ignored)
+      sleep
+    end
+
+    # Wait for t to wait for the mutex and raise it
+    while true
+      sleep 0.1
+      break if t.stop?
+    end
+    t.raise ArgumentError
+    assert(t.alive? || sleeping)
+
+    # Wait for +t+ to reach the sleep
+    while true
+      sleep 0.1
+      break if t.stop?
+    end
+
+    # Now unlock. The mutex should be free, so Mutex#unlock should return nil
+    assert(! m.unlock)
+  end
+
+  def test_mutex_join
+    m = Mutex.new
+    m.lock
+    wt2 = Thread.new do
+      m.lock
+      sleep 0.5
+      m.unlock
+    end
+
+    # Ensure wt2 is waiting on m
+    sleep 0.1
+
+    wt1 = Thread.new do
+      m.lock
+      m.unlock
+    end
+    # Ensure wt1 is waiting on m
+    sleep 0.1
+
+    # Give it to wt2
+    m.unlock
+
+    assert_nothing_raised {wt1.join}
+  end
 end
 
Index: ruby_1_8_7/eval.c
===================================================================
--- ruby_1_8_7/eval.c	(revision 35941)
+++ ruby_1_8_7/eval.c	(revision 35942)
@@ -11566,7 +11566,17 @@
     return rb_thread_join0(rb_thread_check(thread), limit);
 }
 
+void
+rb_thread_set_join(thread, join)
+    VALUE thread, join;
+{
+    rb_thread_t th = rb_thread_check(thread);
+    rb_thread_t jth = rb_thread_check(join);
+    th->wait_for = WAIT_JOIN;
+    th->join = jth;
+}
 
+
 /*
  *  call-seq:
  *     thr.join          => thr

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

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