[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]