[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(¤t->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