[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