Index: prelude.rb =================================================================== --- prelude.rb (リビジョン 30517) +++ prelude.rb (作業コピー) @@ -5,11 +5,13 @@ # Obtains a lock, runs the block, and releases the lock when the # block completes. See the example under Mutex. def synchronize - self.lock begin + self.lock yield ensure - self.unlock rescue nil + if self.own? then + self.unlock rescue nil + end end end end Index: thread.c =================================================================== --- thread.c (リビジョン 30517) +++ thread.c (作業コピー) @@ -3248,6 +3248,22 @@ return self; } +static VALUE +rb_mutex_own(VALUE self) +{ + VALUE owned = Qfalse; + rb_thread_t *th = GET_THREAD(); + mutex_t *mutex; + + GetMutexPtr(self, mutex); + + if (mutex->th == th) + owned = Qtrue; + + return owned; +} + + static const char * mutex_unlock(mutex_t *mutex, rb_thread_t volatile *th) { @@ -4233,6 +4249,7 @@ rb_define_method(rb_cMutex, "lock", rb_mutex_lock, 0); rb_define_method(rb_cMutex, "unlock", rb_mutex_unlock, 0); rb_define_method(rb_cMutex, "sleep", mutex_sleep, -1); + rb_define_method(rb_cMutex, "own?", rb_mutex_own, 0); recursive_key = rb_intern("__recursive_key__"); rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);