diff --git a/lib/monitor.rb b/lib/monitor.rb index 3ded0b3658..cbc1a13a21 100644 --- a/lib/monitor.rb +++ b/lib/monitor.rb @@ -203,6 +203,20 @@ module MonitorMixin end end + # + # Returns true if this monitor is locked by any thread + # + def mon_locked? + @mon_mutex.locked? + end + + # + # Returns true if this monitor is locked by current thread. + # + def mon_owned? + @mon_mutex.locked? && @mon_owner == Thread.current + end + # # Enters exclusive section and executes the block. Leaves the exclusive # section automatically when the block exits. See example under diff --git a/test/monitor/test_monitor.rb b/test/monitor/test_monitor.rb index a3861735b3..ca45602637 100644 --- a/test/monitor/test_monitor.rb +++ b/test/monitor/test_monitor.rb @@ -146,6 +146,35 @@ class TestMonitor < Test::Unit::TestCase assert_join_threads([th, th2]) end + def test_mon_locked_and_owned + queue1 = Queue.new + queue2 = Queue.new + th = Thread.start { + @monitor.enter + queue1.enq(nil) + queue2.deq + @monitor.exit + queue1.enq(nil) + } + queue1.deq + assert(@monitor.mon_locked?) + assert(!@monitor.mon_owned?) + + queue2.enq(nil) + queue1.deq + assert(!@monitor.mon_locked?) + + @monitor.enter + assert @monitor.mon_locked? + assert @monitor.mon_owned? + @monitor.exit + + @monitor.synchronize do + assert @monitor.mon_locked? + assert @monitor.mon_owned? + end + end + def test_cond cond = @monitor.new_cond