mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Monitor#exit: check monitor ownership.
Monitor#exit should be called by only onwer Thread. However, there is not check for it.
This commit is contained in:
parent
fef4370b40
commit
fd6445b7e8
2 changed files with 39 additions and 11 deletions
|
@ -86,10 +86,25 @@ monitor_enter(VALUE monitor)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
monitor_exit(VALUE monitor)
|
||||
monitor_check_owner(VALUE monitor)
|
||||
{
|
||||
struct rb_monitor *mc = monitor_ptr(monitor);
|
||||
if (!mc_owner_p(mc)) {
|
||||
rb_raise(rb_eThreadError, "current thread not owner");
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
monitor_exit(VALUE monitor)
|
||||
{
|
||||
monitor_check_owner(monitor);
|
||||
|
||||
struct rb_monitor *mc = monitor_ptr(monitor);
|
||||
|
||||
if (mc->count <= 0) rb_bug("monitor_exit: count:%d\n", (int)mc->count);
|
||||
mc->count--;
|
||||
|
||||
if (mc->count == 0) {
|
||||
RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
|
||||
rb_mutex_unlock(mc->mutex);
|
||||
|
@ -111,16 +126,6 @@ monitor_owned_p(VALUE monitor)
|
|||
return (rb_mutex_locked_p(mc->mutex) && mc_owner_p(mc)) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
monitor_check_owner(VALUE monitor)
|
||||
{
|
||||
struct rb_monitor *mc = monitor_ptr(monitor);
|
||||
if (!mc_owner_p(mc)) {
|
||||
rb_raise(rb_eThreadError, "current thread not owner");
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
monitor_exit_for_cond(VALUE monitor)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,29 @@ class TestMonitor < Test::Unit::TestCase
|
|||
assert_equal((1..10).to_a, ary)
|
||||
end
|
||||
|
||||
def test_exit
|
||||
m = Monitor.new
|
||||
m.enter
|
||||
assert_equal true, m.mon_owned?
|
||||
m.exit
|
||||
assert_equal false, m.mon_owned?
|
||||
|
||||
assert_raise ThreadError do
|
||||
m.exit
|
||||
end
|
||||
|
||||
assert_equal false, m.mon_owned?
|
||||
|
||||
m.enter
|
||||
Thread.new{
|
||||
assert_raise(ThreadError) do
|
||||
m.exit
|
||||
end
|
||||
}.join
|
||||
assert_equal true, m.mon_owned?
|
||||
m.exit
|
||||
end
|
||||
|
||||
def test_enter_second_after_killed_thread
|
||||
th = Thread.start {
|
||||
@monitor.enter
|
||||
|
|
Loading…
Reference in a new issue