[macruby-changes] [2930] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Oct 30 19:34:43 PDT 2009
Revision: 2930
http://trac.macosforge.org/projects/ruby/changeset/2930
Author: lsansonetti at apple.com
Date: 2009-10-30 19:34:41 -0700 (Fri, 30 Oct 2009)
Log Message:
-----------
implemented VM cleanup + make sure Threads do not leak resources anymore
Modified Paths:
--------------
MacRuby/trunk/include/ruby/intern.h
MacRuby/trunk/thread.c
MacRuby/trunk/vm.cpp
Modified: MacRuby/trunk/include/ruby/intern.h
===================================================================
--- MacRuby/trunk/include/ruby/intern.h 2009-10-30 19:05:50 UTC (rev 2929)
+++ MacRuby/trunk/include/ruby/intern.h 2009-10-31 02:34:41 UTC (rev 2930)
@@ -612,6 +612,7 @@
VALUE rb_struct_define_without_accessor(const char *, VALUE, rb_alloc_func_t, ...);
/* thread.c */
VALUE rb_thgroup_add(VALUE group, VALUE thread);
+void rb_thread_remove_from_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/trunk/thread.c
===================================================================
--- MacRuby/trunk/thread.c 2009-10-30 19:05:50 UTC (rev 2929)
+++ MacRuby/trunk/thread.c 2009-10-31 02:34:41 UTC (rev 2930)
@@ -11,15 +11,25 @@
#include "ruby/node.h"
#include "vm.h"
+VALUE rb_cThread;
+VALUE rb_cThGroup;
+VALUE rb_cMutex;
+
typedef struct rb_vm_mutex {
pthread_mutex_t mutex;
rb_vm_thread_t *thread;
} rb_vm_mutex_t;
-VALUE rb_cThread;
-VALUE rb_cThGroup;
-VALUE rb_cMutex;
+#define GetMutexPtr(obj) ((rb_vm_mutex_t *)DATA_PTR(obj))
+typedef struct {
+ bool enclosed;
+ VALUE threads;
+ VALUE mutex;
+} rb_thread_group_t;
+
+#define GetThreadGroupPtr(obj) ((rb_thread_group_t *)DATA_PTR(obj))
+
#if 0
static VALUE
thread_s_new(int argc, VALUE *argv, VALUE klass)
@@ -53,12 +63,21 @@
// Retain the Thread object to avoid a potential GC, the corresponding
// release is done in rb_vm_thread_run().
- rb_objc_retain((void *)thread);
+ GC_RETAIN(thread);
- if (pthread_create(&t->thread, NULL, (void *(*)(void *))rb_vm_thread_run,
+ // Prepare attributes for the thread.
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ // Launch it.
+ if (pthread_create(&t->thread, &attr, (void *(*)(void *))rb_vm_thread_run,
(void *)thread) != 0) {
rb_sys_fail("pthread_create() failed");
}
+ pthread_attr_destroy(&attr);
return thread;
}
@@ -138,7 +157,14 @@
if (t->status != THREAD_DEAD) {
if (timeout == Qnil) {
// No timeout given: block until the thread finishes.
- pthread_assert(pthread_join(t->thread, NULL));
+ //pthread_assert(pthread_join(t->thread, NULL));
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 10000000;
+ while (t->status != THREAD_DEAD) {
+ nanosleep(&ts, NULL);
+ pthread_yield_np();
+ }
}
else {
// Timeout given: sleep then check if the thread is dead.
@@ -1083,13 +1109,9 @@
* were created.
*/
-typedef struct {
- bool enclosed;
- VALUE threads;
-} rb_thread_group_t;
+static VALUE mutex_s_alloc(VALUE self, SEL sel);
+static VALUE mutex_initialize(VALUE self, SEL sel);
-#define GetThreadGroupPtr(obj) ((rb_thread_group_t *)DATA_PTR(obj))
-
static VALUE
thgroup_s_alloc(VALUE self, SEL sel)
{
@@ -1097,6 +1119,11 @@
sizeof(rb_thread_group_t));
t->enclosed = false;
GC_WB(&t->threads, rb_ary_new());
+
+ VALUE mutex = mutex_s_alloc(rb_cMutex, 0);
+ mutex_initialize(mutex, 0);
+ GC_WB(&t->mutex, mutex);
+
return Data_Wrap_Struct(rb_cThGroup, NULL, NULL, t);
}
@@ -1181,6 +1208,18 @@
* tg group now #<Thread:0x401b3c90>
*/
+static inline void
+thgroup_lock(rb_thread_group_t *tg)
+{
+ pthread_assert(pthread_mutex_lock(&GetMutexPtr(tg->mutex)->mutex));
+}
+
+static inline void
+thgroup_unlock(rb_thread_group_t *tg)
+{
+ pthread_assert(pthread_mutex_unlock(&GetMutexPtr(tg->mutex)->mutex));
+}
+
static VALUE
thgroup_add(VALUE group, SEL sel, VALUE thread)
{
@@ -1197,10 +1236,14 @@
rb_raise(rb_eThreadError,
"can't move from the enclosed thread group");
}
+ thgroup_lock(old_tg);
rb_ary_delete(old_tg->threads, thread);
+ thgroup_unlock(old_tg);
}
+ thgroup_lock(new_tg);
rb_ary_push(new_tg->threads, thread);
+ thgroup_unlock(new_tg);
GC_WB(&t->group, group);
return group;
@@ -1212,6 +1255,21 @@
return thgroup_add(group, 0, thread);
}
+void
+rb_thread_remove_from_group(VALUE thread)
+{
+ rb_vm_thread_t *t = GetThreadPtr(thread);
+ rb_thread_group_t *tg = GetThreadGroupPtr(t->group);
+ thgroup_lock(tg);
+ if (rb_ary_delete(tg->threads, thread) != thread) {
+ printf("trying to remove a thread (%p) from a group that doesn't "\
+ "contain it\n", (void *)thread);
+ abort();
+ }
+ thgroup_unlock(tg);
+ t->group = Qnil;
+}
+
/*
* Document-class: Mutex
*
@@ -1251,8 +1309,6 @@
return Data_Wrap_Struct(rb_cMutex, NULL, NULL, t);
}
-#define GetMutexPtr(obj) ((rb_vm_mutex_t *)DATA_PTR(obj))
-
static VALUE
mutex_initialize(VALUE self, SEL sel)
{
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2009-10-30 19:05:50 UTC (rev 2929)
+++ MacRuby/trunk/vm.cpp 2009-10-31 02:34:41 UTC (rev 2930)
@@ -258,7 +258,6 @@
RoxorCore::~RoxorCore(void)
{
- call_all_finalizers();
// TODO
}
@@ -332,7 +331,17 @@
RoxorVM::~RoxorVM(void)
{
- // TODO
+ for (std::map<void *, rb_vm_block_t *>::iterator i = blocks.begin();
+ i != blocks.end();
+ ++i) {
+ GC_RELEASE(i->second);
+ }
+ blocks.clear();
+
+ GC_RELEASE(backref);
+ GC_RELEASE(broken_with);
+ GC_RELEASE(last_status);
+ GC_RELEASE(errinfo);
}
static void
@@ -3630,7 +3639,7 @@
s->throw_value = Qnil;
s->nested = 1;
catch_jmp_bufs[tag] = s;
- rb_objc_retain((void *)tag);
+ GC_RETAIN(tag);
}
else {
s = iter->second;
@@ -3654,7 +3663,7 @@
s = iter->second;
free(s);
catch_jmp_bufs.erase(iter);
- rb_objc_release((void *)tag);
+ GC_RELEASE(tag);
}
return retval;
@@ -3888,7 +3897,7 @@
GET_CORE()->register_thread(thread);
// Release the thread now.
- rb_objc_release((void *)thread);
+ GC_RELEASE(thread);
rb_vm_thread_t *t = GetThreadPtr(thread);
@@ -3921,6 +3930,7 @@
pthread_cleanup_pop(0);
+ rb_thread_remove_from_group(thread);
GET_CORE()->unregister_thread(thread);
rb_objc_gc_unregister_thread();
@@ -4447,7 +4457,11 @@
printf("functions all=%ld compiled=%ld\n", RoxorCompiler::module->size(),
GET_CORE()->get_functions_compiled());
#endif
-
- delete RoxorCore::shared;
- RoxorCore::shared = NULL;
+
+
+ // XXX: deleting the core is not safe at this point because there might be
+ // threads still running and trying to unregister.
+// delete RoxorCore::shared;
+// RoxorCore::shared = NULL;
+ GET_CORE()->call_all_finalizers();
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091030/5cf34120/attachment-0001.html>
More information about the macruby-changes
mailing list