aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--gc.c5
-rw-r--r--test/ruby/test_gc.rb14
3 files changed, 22 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index c650cb368e..05a44dfc01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Thu Dec 5 10:47:09 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * gc.c (finalize_deferred): flush all deferred finalizers while other
+ finalizers can get ready to run newly by lazy sweep.
+ [ruby-core:58833] [Bug #9205]
+
Thu Dec 5 09:07:59 2013 Aman Gupta <ruby@tmm1.net>
* gc.c (ruby_gc_set_params): Accept safe_level argument so GC tuning
diff --git a/gc.c b/gc.c
index a10c46f878..61812d051e 100644
--- a/gc.c
+++ b/gc.c
@@ -2055,10 +2055,9 @@ finalize_list(rb_objspace_t *objspace, RVALUE *p)
static void
finalize_deferred(rb_objspace_t *objspace)
{
- RVALUE *p = heap_pages_deferred_final;
- heap_pages_deferred_final = 0;
+ RVALUE *p;
- if (p) {
+ while ((p = ATOMIC_PTR_EXCHANGE(heap_pages_deferred_final, 0)) != 0) {
finalize_list(objspace, p);
}
}
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index 034a330c85..41e09b63fb 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -238,4 +238,18 @@ class TestGc < Test::Unit::TestCase
assert_not_nil GC::INTERNAL_CONSTANTS[:HEAP_OBJ_LIMIT]
assert_not_nil GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
end
+
+ def test_sweep_in_finalizer
+ bug9205 = '[ruby-core:58833] [Bug #9205]'
+ 100.times do
+ assert_ruby_status([], <<-'end;', bug9205)
+ raise_proc = proc do |id|
+ GC.start
+ end
+ 1000.times do
+ ObjectSpace.define_finalizer(Object.new, raise_proc)
+ end
+ end;
+ end
+ end
end