From 7be5169804ee0cfe1991903fa10c31f8bd6525bd Mon Sep 17 00:00:00 2001 From: shugo Date: Mon, 18 May 2015 04:56:22 +0000 Subject: * 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 --- ChangeLog | 6 ++++++ lib/monitor.rb | 2 ++ test/monitor/test_monitor.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) 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 + + * 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 * 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 -- cgit v1.2.3