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

source_changes at macosforge.org source_changes at macosforge.org
Wed Jul 8 21:10:34 PDT 2009


Revision: 2005
          http://trac.macosforge.org/projects/ruby/changeset/2005
Author:   lsansonetti at apple.com
Date:     2009-07-08 21:10:34 -0700 (Wed, 08 Jul 2009)
Log Message:
-----------
implemented ThreadGroup + rb_ensure()

Modified Paths:
--------------
    MacRuby/branches/experimental/eval.c
    MacRuby/branches/experimental/include/ruby/intern.h
    MacRuby/branches/experimental/include/ruby/ruby.h
    MacRuby/branches/experimental/thread.c
    MacRuby/branches/experimental/vm.cpp
    MacRuby/branches/experimental/vm.h

Modified: MacRuby/branches/experimental/eval.c
===================================================================
--- MacRuby/branches/experimental/eval.c	2009-07-08 23:41:46 UTC (rev 2004)
+++ MacRuby/branches/experimental/eval.c	2009-07-09 04:10:34 UTC (rev 2005)
@@ -476,15 +476,6 @@
     return (*proc)(data);
 }
 
-VALUE
-rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2)
-{
-    // TODO
-    VALUE result = (*b_proc)(data1);
-    (*e_proc)(data2);
-    return result;
-}
-
 ID
 rb_frame_this_func(void)
 {

Modified: MacRuby/branches/experimental/include/ruby/intern.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/intern.h	2009-07-08 23:41:46 UTC (rev 2004)
+++ MacRuby/branches/experimental/include/ruby/intern.h	2009-07-09 04:10:34 UTC (rev 2005)
@@ -597,6 +597,7 @@
 VALUE rb_struct_alloc_noinit(VALUE);
 VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t, ...);
 /* thread.c */
+VALUE rb_thgroup_add(VALUE group, VALUE thread);
 typedef void rb_unblock_function_t(void *);
 typedef VALUE rb_blocking_function_t(void *);
 VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1,

Modified: MacRuby/branches/experimental/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/ruby.h	2009-07-08 23:41:46 UTC (rev 2004)
+++ MacRuby/branches/experimental/include/ruby/ruby.h	2009-07-09 04:10:34 UTC (rev 2005)
@@ -1059,6 +1059,7 @@
 RUBY_EXTERN VALUE rb_cStruct;
 RUBY_EXTERN VALUE rb_cSymbol;
 RUBY_EXTERN VALUE rb_cThread;
+RUBY_EXTERN VALUE rb_cThGroup;
 RUBY_EXTERN VALUE rb_cTime;
 RUBY_EXTERN VALUE rb_cTrueClass;
 RUBY_EXTERN VALUE rb_cUnboundMethod;

Modified: MacRuby/branches/experimental/thread.c
===================================================================
--- MacRuby/branches/experimental/thread.c	2009-07-08 23:41:46 UTC (rev 2004)
+++ MacRuby/branches/experimental/thread.c	2009-07-09 04:10:34 UTC (rev 2005)
@@ -17,6 +17,7 @@
 } rb_vm_mutex_t;
 
 VALUE rb_cThread;
+VALUE rb_cThGroup;
 VALUE rb_cMutex;
 
 #if 0
@@ -64,6 +65,9 @@
     rb_vm_thread_t *t = GetThreadPtr(thread);
     rb_vm_thread_pre_init(t, b, argc, argv, rb_vm_create_vm());
 
+    // The thread's group is always the parent's one.
+    rb_thgroup_add(GetThreadPtr(rb_vm_current_thread())->group, thread);
+
     // Retain the Thread object to avoid a potential GC, the corresponding
     // release is done in rb_vm_thread_run().
     rb_objc_retain((void *)thread);
@@ -530,11 +534,10 @@
  *     Thread.main.group   #=> #<ThreadGroup:0x4029d914>
  */
 
-VALUE
-rb_thread_group(VALUE thread)
+static VALUE
+rb_thread_group(VALUE thread, SEL sel)
 {
-    // TODO
-    return Qnil;
+    return GetThreadPtr(thread)->group;
 }
 
 /*
@@ -1059,6 +1062,23 @@
  *  were created.
  */
 
+typedef struct {
+    bool enclosed;
+    VALUE threads;
+} rb_thread_group_t;
+
+#define GetThreadGroupPtr(obj) ((rb_thread_group_t *)DATA_PTR(obj))
+
+static VALUE
+thgroup_s_alloc(VALUE self, SEL sel)
+{
+    rb_thread_group_t *t = (rb_thread_group_t *)xmalloc(
+	    sizeof(rb_thread_group_t));
+    t->enclosed = false;
+    GC_WB(&t->threads, rb_ary_new());
+    return Data_Wrap_Struct(rb_cThGroup, NULL, NULL, t);
+}
+
 /*
  *  call-seq:
  *     thgrp.list   => array
@@ -1070,10 +1090,9 @@
  */
 
 static VALUE
-thgroup_list(VALUE group)
+thgroup_list(VALUE group, SEL sel)
 {
-    // TODO
-    return Qnil;
+    return GetThreadGroupPtr(group)->threads;
 }
 
 /*
@@ -1094,10 +1113,11 @@
  *     ThreadError: can't move from the enclosed thread group
  */
 
-VALUE
-thgroup_enclose(VALUE group)
+static VALUE
+thgroup_enclose(VALUE group, SEL sel)
 {
-    return Qnil;
+    GetThreadGroupPtr(group)->enclosed = true;
+    return group;
 }
 
 /*
@@ -1111,7 +1131,7 @@
 static VALUE
 thgroup_enclosed_p(VALUE group)
 {
-    return Qnil;
+    return GetThreadGroupPtr(group)->enclosed ? Qtrue : Qfalse;
 }
 
 /*
@@ -1141,11 +1161,36 @@
  */
 
 static VALUE
-thgroup_add(VALUE group, VALUE thread)
+thgroup_add(VALUE group, SEL sel, VALUE thread)
 {
-    return Qnil;
+    rb_vm_thread_t *t = GetThreadPtr(thread);
+
+    rb_thread_group_t *new_tg = GetThreadGroupPtr(group);
+    if (new_tg->enclosed) {
+	rb_raise(rb_eThreadError, "can't move from the enclosed thread group");
+    }
+
+    if (t->group != Qnil) {
+	rb_thread_group_t *old_tg = GetThreadGroupPtr(t->group);
+	if (old_tg->enclosed) {
+	    rb_raise(rb_eThreadError,
+		    "can't move from the enclosed thread group");
+	}
+	rb_ary_delete(old_tg->threads, thread); 
+    }
+
+    rb_ary_push(new_tg->threads, thread);
+    GC_WB(&t->group, group);
+
+    return group;
 }
 
+VALUE
+rb_thgroup_add(VALUE group, VALUE thread)
+{
+    return thgroup_add(group, 0, thread);
+}
+
 /*
  *  Document-class: Mutex
  *
@@ -1314,20 +1359,27 @@
  */
 
 static VALUE
-mutex_synchronize(VALUE self, SEL sel)
+sync_body(VALUE a)
 {
-    rb_mutex_lock(self, 0);
-    
-    // TODO catch exception
-    VALUE ret = rb_yield(Qundef);
+    return rb_yield(Qundef);
+}
 
-    if (rb_mutex_locked_p(self, 0) == Qtrue) {
+static VALUE
+sync_ensure(VALUE mutex)
+{
+    if (rb_mutex_locked_p(mutex, 0) == Qtrue) {
 	// We only unlock the mutex if it's still locked, since it could have
 	// been unlocked in the block!
-	rb_mutex_unlock(self, 0);
+	rb_mutex_unlock(mutex, 0);
     }
+    return Qnil;
+}
 
-    return ret;
+static VALUE
+mutex_synchronize(VALUE self, SEL sel)
+{
+    rb_mutex_lock(self, 0);
+    return rb_ensure(sync_body, Qundef, sync_ensure, self);
 }
 
 VALUE
@@ -1349,8 +1401,6 @@
 void
 Init_Thread(void)
 {
-    VALUE cThGroup;
-
     rb_cThread = rb_define_class("Thread", rb_cObject);
     rb_objc_define_method(*(VALUE *)rb_cThread, "alloc", thread_s_alloc, 0);
 
@@ -1388,15 +1438,16 @@
     rb_define_method(rb_cThread, "abort_on_exception", rb_thread_abort_exc, 0);
     rb_define_method(rb_cThread, "abort_on_exception=", rb_thread_abort_exc_set, 1);
     rb_define_method(rb_cThread, "safe_level", rb_thread_safe_level, 0);
-    rb_define_method(rb_cThread, "group", rb_thread_group, 0);
+    rb_objc_define_method(rb_cThread, "group", rb_thread_group, 0);
 
     rb_objc_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
 
-    cThGroup = rb_define_class("ThreadGroup", rb_cObject);
-    rb_define_method(cThGroup, "list", thgroup_list, 0);
-    rb_define_method(cThGroup, "enclose", thgroup_enclose, 0);
-    rb_define_method(cThGroup, "enclosed?", thgroup_enclosed_p, 0);
-    rb_define_method(cThGroup, "add", thgroup_add, 1);
+    rb_cThGroup = rb_define_class("ThreadGroup", rb_cObject);
+    rb_objc_define_method(*(VALUE *)rb_cThGroup, "alloc", thgroup_s_alloc, 0);
+    rb_objc_define_method(rb_cThGroup, "list", thgroup_list, 0);
+    rb_objc_define_method(rb_cThGroup, "enclose", thgroup_enclose, 0);
+    rb_objc_define_method(rb_cThGroup, "enclosed?", thgroup_enclosed_p, 0);
+    rb_objc_define_method(rb_cThGroup, "add", thgroup_add, 1);
 
     rb_cMutex = rb_define_class("Mutex", rb_cObject);
     rb_objc_define_method(*(VALUE *)rb_cMutex, "alloc", mutex_s_alloc, 0);

Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp	2009-07-08 23:41:46 UTC (rev 2004)
+++ MacRuby/branches/experimental/vm.cpp	2009-07-09 04:10:34 UTC (rev 2005)
@@ -3792,6 +3792,22 @@
 }
 
 extern "C"
+VALUE
+rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1,
+	VALUE (*e_proc)(ANYARGS), VALUE data2)
+{
+    try {
+	VALUE v = (*b_proc)(data1);
+	(*e_proc)(data2);
+	return v;
+    }
+    catch (...) {
+	(*e_proc)(data2);
+	throw;	
+    }
+}
+
+extern "C"
 void
 rb_vm_break(VALUE val)
 {
@@ -4563,6 +4579,7 @@
     t->exception = Qnil;
     t->status = THREAD_ALIVE;
     t->in_cond_wait = false;
+    t->group = Qnil; // will be set right after
 
     pthread_assert(pthread_mutex_init(&t->sleep_mutex, NULL));
     pthread_assert(pthread_cond_init(&t->sleep_cond, NULL)); 
@@ -4833,7 +4850,7 @@
 void
 Init_PostVM(void)
 {
-    // Create and register the main thread;
+    // Create and register the main thread.
     RoxorVM *main_vm = GET_VM();
     rb_vm_thread_t *t = (rb_vm_thread_t *)xmalloc(sizeof(rb_vm_thread_t));
     rb_vm_thread_pre_init(t, NULL, 0, NULL, (void *)main_vm);
@@ -4841,6 +4858,11 @@
     VALUE main = Data_Wrap_Struct(rb_cThread, NULL, NULL, t);
     GET_CORE()->register_thread(main);
     main_vm->set_thread(main);
+
+    // Create main thread group.
+    VALUE group = rb_obj_alloc(rb_cThGroup);
+    rb_thgroup_add(group, main);
+    rb_define_const(rb_cThGroup, "Default", group);
 }
 
 extern "C"

Modified: MacRuby/branches/experimental/vm.h
===================================================================
--- MacRuby/branches/experimental/vm.h	2009-07-08 23:41:46 UTC (rev 2004)
+++ MacRuby/branches/experimental/vm.h	2009-07-09 04:10:34 UTC (rev 2005)
@@ -101,14 +101,15 @@
     rb_vm_block_t *body;
     int argc;
     const VALUE *argv;
-    void *vm;  // an instance of RoxorVM
+    void *vm;  // a C++ instance of RoxorVM
     VALUE value;
     pthread_mutex_t sleep_mutex;
     pthread_cond_t sleep_cond;
     rb_vm_thread_status_t status;
     bool in_cond_wait;
     VALUE locals;  // a Hash object or Qnil
-    VALUE exception;  // killed-by-exception or Qnil 
+    VALUE exception;  // killed-by exception or Qnil 
+    VALUE group;  // always a ThreadGroup object
 } 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/20090708/dba1ed3c/attachment-0001.html>


More information about the macruby-changes mailing list