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
|
static VALUE
|
||||||
monitor_exit(VALUE monitor)
|
monitor_check_owner(VALUE monitor)
|
||||||
{
|
{
|
||||||
struct rb_monitor *mc = monitor_ptr(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--;
|
mc->count--;
|
||||||
|
|
||||||
if (mc->count == 0) {
|
if (mc->count == 0) {
|
||||||
RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
|
RB_OBJ_WRITE(monitor, &mc->owner, Qnil);
|
||||||
rb_mutex_unlock(mc->mutex);
|
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;
|
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
|
static VALUE
|
||||||
monitor_exit_for_cond(VALUE monitor)
|
monitor_exit_for_cond(VALUE monitor)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,29 @@ class TestMonitor < Test::Unit::TestCase
|
||||||
assert_equal((1..10).to_a, ary)
|
assert_equal((1..10).to_a, ary)
|
||||||
end
|
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
|
def test_enter_second_after_killed_thread
|
||||||
th = Thread.start {
|
th = Thread.start {
|
||||||
@monitor.enter
|
@monitor.enter
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue