[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