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);
