[macruby-changes] [2926] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Oct 29 23:34:13 PDT 2009
Revision: 2926
http://trac.macosforge.org/projects/ruby/changeset/2926
Author: lsansonetti at apple.com
Date: 2009-10-29 23:34:13 -0700 (Thu, 29 Oct 2009)
Log Message:
-----------
unregister VM objects created from GCD pthreads
Modified Paths:
--------------
MacRuby/trunk/eval.c
MacRuby/trunk/gcd.c
MacRuby/trunk/vm.cpp
MacRuby/trunk/vm.h
Modified: MacRuby/trunk/eval.c
===================================================================
--- MacRuby/trunk/eval.c 2009-10-30 04:12:21 UTC (rev 2925)
+++ MacRuby/trunk/eval.c 2009-10-30 06:34:13 UTC (rev 2926)
@@ -38,6 +38,7 @@
void Init_ext(void);
void Init_PreGC(void);
void Init_PreVM(void);
+void Init_PreGCD(void);
bool ruby_dlog_enabled = false;
FILE *ruby_dlog_file = NULL;
@@ -73,6 +74,7 @@
Init_PreGC();
Init_PreVM();
+ Init_PreGCD();
rb_call_inits();
ruby_prog_init();
Modified: MacRuby/trunk/gcd.c
===================================================================
--- MacRuby/trunk/gcd.c 2009-10-30 04:12:21 UTC (rev 2925)
+++ MacRuby/trunk/gcd.c 2009-10-30 06:34:13 UTC (rev 2926)
@@ -846,7 +846,41 @@
}
}
+// GCD callbacks that will let us know when a POSIX thread is started / ended.
+// We can appropriately create/delete a RoxorVM object based on that.
+static void (*old_dispatch_begin_thread_4GC)(void) = NULL;
+static void (*old_dispatch_end_thread_4GC)(void) = NULL;
+extern void (*dispatch_begin_thread_4GC)(void);
+extern void (*dispatch_end_thread_4GC)(void);
+
+static void
+rb_dispatch_begin_thread(void)
+{
+ if (old_dispatch_begin_thread_4GC != NULL) {
+ (*old_dispatch_begin_thread_4GC)();
+ }
+ rb_vm_register_current_alien_thread();
+}
+
+static void
+rb_dispatch_end_thread(void)
+{
+ if (old_dispatch_end_thread_4GC != NULL) {
+ (*old_dispatch_end_thread_4GC)();
+ }
+ rb_vm_unregister_current_alien_thread();
+}
+
void
+Init_PreGCD(void)
+{
+ old_dispatch_begin_thread_4GC = dispatch_begin_thread_4GC;
+ old_dispatch_end_thread_4GC = dispatch_end_thread_4GC;
+ dispatch_begin_thread_4GC = rb_dispatch_begin_thread;
+ dispatch_end_thread_4GC = rb_dispatch_end_thread;
+}
+
+void
Init_Dispatch(void)
{
high_priority_id = rb_intern("high");
@@ -928,6 +962,12 @@
#else
void
+Init_PreGCD(void)
+{
+ // Do nothing...
+}
+
+void
Init_Dispatch(void)
{
// Do nothing...
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2009-10-30 04:12:21 UTC (rev 2925)
+++ MacRuby/trunk/vm.cpp 2009-10-30 06:34:13 UTC (rev 2926)
@@ -4374,13 +4374,54 @@
rb_vm_thread_pre_init(t, NULL, 0, NULL, (void *)this);
t->thread = pthread_self();
- VALUE main = Data_Wrap_Struct(rb_cThread, NULL, NULL, t);
- GET_CORE()->register_thread(main);
- this->set_thread(main);
+ VALUE thread = Data_Wrap_Struct(rb_cThread, NULL, NULL, t);
+ GET_CORE()->register_thread(thread);
+ this->set_thread(thread);
}
extern "C"
void
+rb_vm_register_current_alien_thread(void)
+{
+ // This callback is not used, we prefer to create RoxorVM objects
+ // lazily (in RoxorVM::current()), for performance reasons, because the
+ // callback is called *a lot* and most of the time from various parts of
+ // the system which will never ask us to execute Ruby code.
+#if 0
+ if (GET_CORE()->get_running()) {
+ printf("registered alien thread %p\n", pthread_self());
+ RoxorVM *vm = new RoxorVM();
+ vm->setup_from_current_thread();
+ }
+#endif
+}
+
+extern "C"
+void
+rb_vm_unregister_current_alien_thread(void)
+{
+ // Check if the current pthread has been registered.
+ GET_CORE()->lock();
+ pthread_t self = pthread_self();
+ VALUE ary = GET_CORE()->get_threads();
+ bool need_to_unregister = false;
+ for (int i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE t = RARRAY_AT(ary, i);
+ if (GetThreadPtr(t)->thread == self) {
+ need_to_unregister = true;
+ }
+ }
+ GET_CORE()->unlock();
+
+ // If yes, appropriately unregister it.
+ if (need_to_unregister) {
+ //printf("unregistered alien thread %p\n", pthread_self());
+ GET_CORE()->unregister_thread(GET_VM()->get_thread());
+ }
+}
+
+extern "C"
+void
Init_PostVM(void)
{
// Create and register the main thread.
Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h 2009-10-30 04:12:21 UTC (rev 2925)
+++ MacRuby/trunk/vm.h 2009-10-30 06:34:13 UTC (rev 2926)
@@ -394,6 +394,9 @@
void rb_vm_thread_cancel(rb_vm_thread_t *t);
void rb_vm_thread_raise(rb_vm_thread_t *t, VALUE exc);
+void rb_vm_register_current_alien_thread(void);
+void rb_vm_unregister_current_alien_thread(void);
+
bool rb_vm_abort_on_exception(void);
void rb_vm_set_abort_on_exception(bool flag);
@@ -811,7 +814,6 @@
// create a new VM object just for this thread.
// XXX the VM object is never detroyed.
RoxorVM *new_vm = new RoxorVM();
- pthread_setspecific(vm_thread_key, (void *)new_vm);
new_vm->setup_from_current_thread();
return new_vm;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091029/7baa1506/attachment.html>
More information about the macruby-changes
mailing list