[macruby-changes] [2079] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Fri Jul 24 22:52:26 PDT 2009


Revision: 2079
          http://trac.macosforge.org/projects/ruby/changeset/2079
Author:   lsansonetti at apple.com
Date:     2009-07-24 22:52:26 -0700 (Fri, 24 Jul 2009)
Log Message:
-----------
unlocked mutexes are now automatically unlocked once the thread that locked them dies + raise an exception when trying to unlock a mutex that is locked by another thread

Modified Paths:
--------------
    MacRuby/branches/experimental/thread.c
    MacRuby/branches/experimental/vm.cpp
    MacRuby/branches/experimental/vm.h

Modified: MacRuby/branches/experimental/thread.c
===================================================================
--- MacRuby/branches/experimental/thread.c	2009-07-25 05:51:08 UTC (rev 2078)
+++ MacRuby/branches/experimental/thread.c	2009-07-25 05:52:26 UTC (rev 2079)
@@ -1291,6 +1291,10 @@
     pthread_assert(pthread_mutex_lock(&m->mutex));
     current->status = THREAD_ALIVE;
     m->thread = current;
+    if (current->mutexes == Qnil) {
+	GC_WB(&current->mutexes, rb_ary_new());
+    }
+    rb_ary_push(current->mutexes, self);
 
     return self;
 }
@@ -1303,21 +1307,45 @@
  * Raises +ThreadError+ if +mutex+ wasn't locked by the current thread.
  */
 
-static VALUE
-rb_mutex_unlock(VALUE self, SEL sel)
+static void
+rb_mutex_unlock0(VALUE self, bool delete_from_thread_mutexes)
 {
     rb_vm_mutex_t *m = GetMutexPtr(self);
-    if (m->thread == 0) {
+    if (m->thread == NULL) {
 	rb_raise(rb_eThreadError,
 		"Attempt to unlock a mutex which is not locked");
     }
-
+    else if (m->thread != GetThreadPtr(rb_vm_current_thread())) {
+	rb_raise(rb_eThreadError,
+		"Attempt to unlock a mutex which is locked by another thread");
+    }
+    if (delete_from_thread_mutexes) {
+	assert(m->thread->mutexes != Qnil);
+	rb_ary_delete(m->thread->mutexes, self);
+    }
     pthread_assert(pthread_mutex_unlock(&m->mutex));
-    m->thread = 0;
+    m->thread = NULL;
+}
 
+static VALUE
+rb_mutex_unlock(VALUE self, SEL sel)
+{
+    rb_mutex_unlock0(self, true);
     return self;
 }
 
+void
+rb_thread_unlock_all_mutexes(rb_vm_thread_t *thread)
+{
+    if (thread->mutexes != Qnil) {
+	int i, count = RARRAY_LEN(thread->mutexes);
+	for (i = 0; i < count; i++) {
+	    rb_mutex_unlock0(RARRAY_AT(thread->mutexes, i), false);  
+	}
+	rb_ary_clear(thread->mutexes);
+    }
+}
+
 /*
  * call-seq:
  *    mutex.sleep(timeout = nil)    => number

Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp	2009-07-25 05:51:08 UTC (rev 2078)
+++ MacRuby/branches/experimental/vm.cpp	2009-07-25 05:52:26 UTC (rev 2079)
@@ -4405,6 +4405,8 @@
     vm->set_thread(thread);
 }
 
+extern "C" void rb_thread_unlock_all_mutexes(rb_vm_thread_t *thread);
+
 void
 RoxorCore::unregister_thread(VALUE thread)
 {
@@ -4431,6 +4433,8 @@
     }
     pthread_assert(pthread_cond_destroy(&t->sleep_cond));
 
+    rb_thread_unlock_all_mutexes(t); 
+
     RoxorVM *vm = (RoxorVM *)t->vm;
     delete vm;
     t->vm = NULL;
@@ -4577,6 +4581,7 @@
     t->status = THREAD_ALIVE;
     t->in_cond_wait = false;
     t->group = Qnil; // will be set right after
+    t->mutexes = Qnil;
 
     pthread_assert(pthread_mutex_init(&t->sleep_mutex, NULL));
     pthread_assert(pthread_cond_init(&t->sleep_cond, NULL)); 

Modified: MacRuby/branches/experimental/vm.h
===================================================================
--- MacRuby/branches/experimental/vm.h	2009-07-25 05:51:08 UTC (rev 2078)
+++ MacRuby/branches/experimental/vm.h	2009-07-25 05:52:26 UTC (rev 2079)
@@ -110,6 +110,7 @@
     VALUE locals;  // a Hash object or Qnil
     VALUE exception;  // killed-by exception or Qnil 
     VALUE group;  // always a ThreadGroup object
+    VALUE mutexes;  // an Array object or Qnil
 } rb_vm_thread_t;
 
 typedef struct rb_vm_outer {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090724/c7061e53/attachment.html>


More information about the macruby-changes mailing list