summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--NEWS3
-rw-r--r--test/ruby/test_thread.rb29
-rw-r--r--thread.c23
4 files changed, 63 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 32136aea00..3137a4b388 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed Dec 5 00:56:21 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+
+ * thread.c (rb_mutex_owned_p): new method that return current
+ thread have the target mutex or not. [Feature #7505] [ruby-dev:46697]
+ * test/ruby/test_thread.rb (test_mutex_owned, test_mutex_owned2):
+ test for the above.
+ * NEWS: new for the above.
+
Wed Dec 5 00:05:47 2012 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
* lib/erb.rb (make_compiler, add_put_cmd, add_insert_cmd): extract
diff --git a/NEWS b/NEWS
index d4c19a5a90..db31e6773f 100644
--- a/NEWS
+++ b/NEWS
@@ -113,6 +113,9 @@ with all sufficient information, see the ChangeLog file.
Object.const_get("Foo::Bar::Baz")
* Mutex
+ * added method:
+ * added Mutex#owned? which returns the mutex is held by current
+ thread or not. [experimental]
* incompatible changes:
* Mutex#lock, Mutex#unlock, Mutex#try_lock, Mutex#synchronize
and Mutex#sleep are no longer allowed to be used from trap handler
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index 0149e17d53..e180310505 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -797,4 +797,33 @@ Thread.new(Thread.current) {|mth|
sleep 0.01
assert_equal(ary, ["run", "aborting", "aborting"])
end
+
+ def test_mutex_owned
+ mutex = Mutex.new
+
+ assert_equal(mutex.owned?, false)
+ mutex.synchronize {
+ # Now, I have the mutex
+ assert_equal(mutex.owned?, true)
+ }
+ assert_equal(mutex.owned?, false)
+ end
+
+ def test_mutex_owned2
+ begin
+ mutex = Mutex.new
+ th = Thread.new {
+ # lock forever
+ mutex.lock
+ sleep
+ }
+
+ sleep 0.01 until th.status == "sleep"
+ # acquired another thread.
+ assert_equal(mutex.locked?, true)
+ assert_equal(mutex.owned?, false)
+ ensure
+ th.kill if th
+ end
+ end
end
diff --git a/thread.c b/thread.c
index b1127a7e3a..3aeebaf13a 100644
--- a/thread.c
+++ b/thread.c
@@ -4251,6 +4251,28 @@ rb_mutex_lock(VALUE self)
return self;
}
+/*
+ * call-seq:
+ * mutex.owned? -> true or false
+ *
+ * Returns +true+ if this lock is currently held by current thread.
+ * <em>This API is experimental, and subject to change.</em>
+ */
+static VALUE
+rb_mutex_owned_p(VALUE self)
+{
+ VALUE owned = Qfalse;
+ rb_thread_t *th = GET_THREAD();
+ rb_mutex_t *mutex;
+
+ GetMutexPtr(self, mutex);
+
+ if (mutex->th == th)
+ owned = Qtrue;
+
+ return owned;
+}
+
static const char *
rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t volatile *th)
{
@@ -4874,6 +4896,7 @@ Init_Thread(void)
rb_define_method(rb_cMutex, "unlock", rb_mutex_unlock, 0);
rb_define_method(rb_cMutex, "sleep", mutex_sleep, -1);
rb_define_method(rb_cMutex, "synchronize", rb_mutex_synchronize_m, 0);
+ rb_define_method(rb_cMutex, "owned?", rb_mutex_owned_p, 0);
recursive_key = rb_intern("__recursive_key__");
rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);