ruby-changes:21312
From: nobu <ko1@a...>
Date: Fri, 30 Sep 2011 01:54:25 +0900 (JST)
Subject: [ruby-changes:21312] nobu:r33361 (trunk): * gc.c (slot_sweep, rb_gc_finalize_deferred)
nobu 2011-09-30 01:54:14 +0900 (Fri, 30 Sep 2011) New Revision: 33361 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33361 Log: * gc.c (slot_sweep, rb_gc_finalize_deferred) (rb_objspace_call_finalizer, rb_gc): run finalizers sequencially. [ruby-dev:44562] Modified files: trunk/ChangeLog trunk/gc.c Index: ChangeLog =================================================================== --- ChangeLog (revision 33360) +++ ChangeLog (revision 33361) @@ -1,3 +1,9 @@ +Thu Sep 29 11:53:56 2011 Nobuyoshi Nakada <nobu@r...> + + * gc.c (slot_sweep, rb_gc_finalize_deferred) + (rb_objspace_call_finalizer, rb_gc): run finalizers + sequencially. [ruby-dev:44562] + Thu Sep 29 20:37:38 2011 Nobuyoshi Nakada <nobu@r...> * ext/gdbm/gdbm.c (rb_gdbm_fatal): adjust argument type. Index: gc.c =================================================================== --- gc.c (revision 33360) +++ gc.c (revision 33361) @@ -345,6 +345,7 @@ int dont_gc; int dont_lazy_sweep; int during_gc; + rb_atomic_t finalizing; } flags; struct { st_table *table; @@ -387,6 +388,7 @@ #define heaps_freed objspace->heap.freed #define dont_gc objspace->flags.dont_gc #define during_gc objspace->flags.during_gc +#define finalizing objspace->flags.finalizing #define finalizer_table objspace->final.table #define deferred_final_list objspace->final.deferred #define mark_stack objspace->markstack.buffer @@ -2064,7 +2066,7 @@ } objspace->heap.final_num += final_num; - if (deferred_final_list) { + if (deferred_final_list && !finalizing) { rb_thread_t *th = GET_THREAD(); if (th) { RUBY_VM_SET_FINALIZER_INTERRUPT(th); @@ -2968,7 +2970,10 @@ void rb_gc_finalize_deferred(void) { - finalize_deferred(&rb_objspace); + rb_objspace_t *objspace = &rb_objspace; + if (ATOMIC_SET(finalizing, 1)) return; + finalize_deferred(objspace); + ATOMIC_SET(finalizing, 0); } static int @@ -3020,6 +3025,8 @@ /* run finalizers */ gc_clear_mark_on_sweep_slots(objspace); + if (ATOMIC_SET(finalizing, 1)) return; + do { /* XXX: this loop will make no sense */ /* because mark will not be removed */ @@ -3082,6 +3089,7 @@ st_free_table(finalizer_table); finalizer_table = 0; + ATOMIC_SET(finalizing, 0); } void @@ -3089,7 +3097,7 @@ { rb_objspace_t *objspace = &rb_objspace; garbage_collect(objspace); - finalize_deferred(objspace); + if (!finalizing) finalize_deferred(objspace); free_unused_heaps(objspace); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/