aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-18 04:56:22 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-18 04:56:22 +0000
commit7be5169804ee0cfe1991903fa10c31f8bd6525bd (patch)
tree0b8129f5a0b2fc9a19d6b12ae5eb966b7a6e2128
parent47349e870111b8ae88bd1331559a022be88d80ec (diff)
downloadruby-7be5169804ee0cfe1991903fa10c31f8bd6525bd.tar.gz
* lib/monitor.rb (mon_try_enter, mon_enter): should reset @mon_count
just in case the previous owner thread dies without mon_exit. [fix GH-874] Patch by @chrisberkhout git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50525 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--lib/monitor.rb2
-rw-r--r--test/monitor/test_monitor.rb32
3 files changed, 40 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index cece151162..faf099b172 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Mon May 18 13:55:01 2015 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/monitor.rb (mon_try_enter, mon_enter): should reset @mon_count
+ just in case the previous owner thread dies without mon_exit.
+ [fix GH-874] Patch by @chrisberkhout
+
Sun May 17 17:21:29 2015 Eric Wong <e@80x24.org>
* lib/webrick/utils.rb (set_non_blocking): use IO#nonblock=
diff --git a/lib/monitor.rb b/lib/monitor.rb
index 07394b5900..e0491ec054 100644
--- a/lib/monitor.rb
+++ b/lib/monitor.rb
@@ -170,6 +170,7 @@ module MonitorMixin
return false
end
@mon_owner = Thread.current
+ @mon_count = 0
end
@mon_count += 1
return true
@@ -184,6 +185,7 @@ module MonitorMixin
if @mon_owner != Thread.current
@mon_mutex.lock
@mon_owner = Thread.current
+ @mon_count = 0
end
@mon_count += 1
end
diff --git a/test/monitor/test_monitor.rb b/test/monitor/test_monitor.rb
index 451e26cc7a..088bf28a37 100644
--- a/test/monitor/test_monitor.rb
+++ b/test/monitor/test_monitor.rb
@@ -33,6 +33,22 @@ class TestMonitor < Test::Unit::TestCase
assert_equal((1..10).to_a, ary)
end
+ def test_enter_second_after_killed_thread
+ th = Thread.start {
+ @monitor.enter
+ Thread.current.kill
+ @monitor.exit
+ }
+ th.join
+ @monitor.enter
+ @monitor.exit
+ th2 = Thread.start {
+ @monitor.enter
+ @monitor.exit
+ }
+ assert_join_threads([th, th2])
+ end
+
def test_synchronize
ary = []
queue = Queue.new
@@ -111,6 +127,22 @@ class TestMonitor < Test::Unit::TestCase
assert_join_threads([th, th2])
end
+ def test_try_enter_second_after_killed_thread
+ th = Thread.start {
+ assert_equal(true, @monitor.try_enter)
+ Thread.current.kill
+ @monitor.exit
+ }
+ th.join
+ assert_equal(true, @monitor.try_enter)
+ @monitor.exit
+ th2 = Thread.start {
+ assert_equal(true, @monitor.try_enter)
+ @monitor.exit
+ }
+ assert_join_threads([th, th2])
+ end
+
def test_cond
cond = @monitor.new_cond