[macruby-changes] [2921] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu Oct 29 16:36:01 PDT 2009


Revision: 2921
          http://trac.macosforge.org/projects/ruby/changeset/2921
Author:   lsansonetti at apple.com
Date:     2009-10-29 16:36:01 -0700 (Thu, 29 Oct 2009)
Log Message:
-----------
call pending ObjectSpace finalizers before exiting

Modified Paths:
--------------
    MacRuby/trunk/eval.c
    MacRuby/trunk/gc.c
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h

Modified: MacRuby/trunk/eval.c
===================================================================
--- MacRuby/trunk/eval.c	2009-10-29 23:35:15 UTC (rev 2920)
+++ MacRuby/trunk/eval.c	2009-10-29 23:36:01 UTC (rev 2921)
@@ -97,7 +97,6 @@
     rb_vm_finalize();
     ruby_sig_finalize();
     //GET_THREAD()->errinfo = Qnil;
-    rb_gc_call_finalizer_at_exit();
 }
 
 void

Modified: MacRuby/trunk/gc.c
===================================================================
--- MacRuby/trunk/gc.c	2009-10-29 23:35:15 UTC (rev 2920)
+++ MacRuby/trunk/gc.c	2009-10-29 23:36:01 UTC (rev 2921)
@@ -726,11 +726,6 @@
  *
  */
 
-typedef struct {
-    VALUE klass;
-    VALUE finalizers;
-} rb_vm_finalizer_t;
-
 static VALUE rb_cFinalizer;
 
 static void *finalizer_key = NULL; // only used for its address
@@ -742,13 +737,10 @@
 static void
 rb_objc_finalizer_finalize(void *rcv, SEL sel)
 {
-    rb_vm_set_multithreaded(true);
     rb_vm_finalizer_t *f = (rb_vm_finalizer_t *)rcv;
-    for (int i = 0, count = RARRAY_LEN(f->finalizers); i < count; i++) {
-	VALUE b = RARRAY_AT(f->finalizers, i);
-	VALUE objid = rb_obj_id((VALUE)rcv, 0);
-	rb_vm_call(b, selCall, 1, &objid, false);	
-    }
+    rb_vm_set_multithreaded(true);
+    rb_vm_call_finalizer(f);
+    rb_vm_unregister_finalizer(f); 
     if (rb_objc_finalizer_finalize_super != NULL) {
 	((void(*)(void *, SEL))rb_objc_finalizer_finalize_super)(rcv, sel);
     }
@@ -764,6 +756,7 @@
 	    &finalizer_key);
     if (finalizer != NULL) {
 	rb_ary_clear(finalizer->finalizers);
+	rb_vm_unregister_finalizer(finalizer); 
 	rb_objc_set_associative_ref((void *)obj, &finalizer_key, NULL);
     }
     return obj;
@@ -802,8 +795,10 @@
 	finalizer = (rb_vm_finalizer_t *)
 	    rb_objc_newobj(sizeof(rb_vm_finalizer_t *));
 	finalizer->klass = rb_cFinalizer;
+	finalizer->objid = rb_obj_id(obj, 0);
 	GC_WB(&finalizer->finalizers, rb_ary_new());
 	rb_objc_set_associative_ref((void *)obj, &finalizer_key, finalizer);
+	rb_vm_register_finalizer(finalizer); 
     }
 
     rb_ary_push(finalizer->finalizers, block);
@@ -818,13 +813,6 @@
     // TODO
 }
 
-void
-rb_gc_call_finalizer_at_exit(void)
-{
-    // This should magically trigger -[__Finalizer finalize].
-    auto_collect(__auto_zone, AUTO_COLLECT_FULL_COLLECTION, NULL);
-}
-
 /*
  *  call-seq:
  *     ObjectSpace._id2ref(object_id) -> an_object

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2009-10-29 23:35:15 UTC (rev 2920)
+++ MacRuby/trunk/vm.cpp	2009-10-29 23:36:01 UTC (rev 2921)
@@ -256,6 +256,12 @@
 #endif
 }
 
+RoxorCore::~RoxorCore(void)
+{
+    call_all_finalizers();
+    // TODO
+}
+
 RoxorVM::RoxorVM(void)
 {
     current_top_object = Qnil;
@@ -3715,6 +3721,73 @@
 }
 
 extern "C"
+void
+rb_vm_register_finalizer(rb_vm_finalizer_t *finalizer)
+{
+    GET_CORE()->register_finalizer(finalizer);
+}
+
+extern "C"
+void
+rb_vm_unregister_finalizer(rb_vm_finalizer_t *finalizer)
+{
+    GET_CORE()->unregister_finalizer(finalizer);
+}
+
+void
+RoxorCore::register_finalizer(rb_vm_finalizer_t *finalizer)
+{
+    lock();
+    finalizers.push_back(finalizer);
+    unlock();
+}
+
+void
+RoxorCore::unregister_finalizer(rb_vm_finalizer_t *finalizer)
+{
+    lock();
+    std::vector<rb_vm_finalizer_t *>::iterator i = std::find(finalizers.begin(),
+	    finalizers.end(), finalizer);
+    if (i != finalizers.end()) {
+	finalizers.erase(i);
+    }
+    unlock();
+}
+
+static void
+call_finalizer(rb_vm_finalizer_t *finalizer)
+{
+    for (int i = 0, count = RARRAY_LEN(finalizer->finalizers); i < count; i++) {
+	VALUE b = RARRAY_AT(finalizer->finalizers, i);
+	try {
+	    rb_vm_call(b, selCall, 1, &finalizer->objid, false);
+	}
+	catch (...) {
+	    // Do nothing.
+	}
+    }
+    rb_ary_clear(finalizer->finalizers);
+}
+
+extern "C"
+void
+rb_vm_call_finalizer(rb_vm_finalizer_t *finalizer)
+{
+    call_finalizer(finalizer);
+}
+
+void
+RoxorCore::call_all_finalizers(void)
+{
+    for (std::vector<rb_vm_finalizer_t *>::iterator i = finalizers.begin();
+	    i != finalizers.end();
+	    ++i) {
+	call_finalizer(*i);
+    }
+    finalizers.clear();
+}
+
+extern "C"
 void *
 rb_vm_create_vm(void)
 {
@@ -4332,4 +4405,7 @@
     printf("functions all=%ld compiled=%ld\n", RoxorCompiler::module->size(),
 	    GET_CORE()->get_functions_compiled());
 #endif
+    
+    delete RoxorCore::shared;
+    RoxorCore::shared = NULL;
 }

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2009-10-29 23:35:15 UTC (rev 2920)
+++ MacRuby/trunk/vm.h	2009-10-29 23:36:01 UTC (rev 2921)
@@ -447,6 +447,16 @@
 
 void rb_vm_set_current_scope(VALUE mod, rb_vm_scope_t scope);
 
+typedef struct {
+    VALUE klass;
+    VALUE objid;
+    VALUE finalizers;
+} rb_vm_finalizer_t;
+
+void rb_vm_register_finalizer(rb_vm_finalizer_t *finalizer);
+void rb_vm_unregister_finalizer(rb_vm_finalizer_t *finalizer);
+void rb_vm_call_finalizer(rb_vm_finalizer_t *finalizer);
+
 VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
 VALUE rb_iseq_eval(VALUE iseq);
 VALUE rb_iseq_new(NODE *node, VALUE filename);
@@ -548,6 +558,11 @@
 	// Running threads.
 	VALUE threads;
 
+	// Finalizers. They are automatically called during garbage collection
+	// but we still need to keep a list of them, because the list may not
+	// be empty when we exit and we need to call the remaining finalizers.
+	std::vector<rb_vm_finalizer_t *> finalizers;
+
 	// State.
 	bool running;
 	bool multithreaded;
@@ -604,6 +619,7 @@
 
     public:
 	RoxorCore(void);
+	~RoxorCore(void);
 
 	ACCESSOR(running, bool);
 	ACCESSOR(multithreaded, bool);
@@ -744,6 +760,10 @@
 	size_t get_sizeof(const char *type);
 	bool is_large_struct_type(const Type *type);
 
+	void register_finalizer(rb_vm_finalizer_t *finalizer);
+	void unregister_finalizer(rb_vm_finalizer_t *finalizer);
+	void call_all_finalizers(void);
+
     private:
 	bool register_bs_boxed(bs_element_type_t type, void *value);
 	void register_bs_class(bs_element_class_t *bs_class);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091029/df0fa980/attachment-0001.html>


More information about the macruby-changes mailing list