[pypy-commit] stmgc use-gcc: questions with failing test about finalizers
Raemi
noreply at buildbot.pypy.org
Wed Aug 26 16:39:23 CEST 2015
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: use-gcc
Changeset: r1945:824bc70d6f36
Date: 2015-08-26 16:43 +0200
http://bitbucket.org/pypy/stmgc/changeset/824bc70d6f36/
Log: questions with failing test about finalizers
diff --git a/c8/stm/finalizer.c b/c8/stm/finalizer.c
--- a/c8/stm/finalizer.c
+++ b/c8/stm/finalizer.c
@@ -481,6 +481,13 @@
LIST_FREE(f->run_finalizers);
}
+/* XXX: can there be a race between _invoke_general_finalizers
+ and _commit_finalizer on g_finalizers (+other places?)?
+ XXX: what happens in _execute_finalizer if the transaction
+ conflicts (or fails to become inevitable) in a finalizer?
+ (the run_finalizers list is half-way cleared?)
+*/
+
static void _invoke_general_finalizers(stm_thread_local_t *tl)
{
/* called between transactions */
@@ -496,6 +503,7 @@
stm_rewind_jmp_enterframe(tl, &rjbuf);
_stm_start_transaction(tl);
+ fprintf(stderr, "run_finalizers: %lu\n", list_count(g_finalizers.run_finalizers));
_execute_finalizers(&g_finalizers);
_stm_commit_transaction();
diff --git a/c8/test/test_finalizer.py b/c8/test/test_finalizer.py
--- a/c8/test/test_finalizer.py
+++ b/c8/test/test_finalizer.py
@@ -139,6 +139,7 @@
self.expect_finalized([lp1], from_tlnum=0)
+
class TestRegularFinalizer(BaseTest):
expect_content_character = None
run_major_collect_in_finalizer = False
@@ -272,3 +273,59 @@
self.expect_finalized([])
stm_major_collect()
self.expect_finalized([lp1])
+
+
+class TestMoreRegularFinalizers(BaseTest):
+
+ def test_inevitable_in_finalizer(self):
+ lpo = stm_allocate_old(16)
+
+ self._first_time = True
+ @ffi.callback("void(object_t *)")
+ def finalizer(obj):
+ print "finalizing!", obj
+ stm_set_char(lpo, 'a')
+
+ if self._first_time:
+ self._first_time = False
+ # we will switch to the other TX and
+ # make it inevitable, so that our TX
+ # will abort on commit (or validate)
+ self.switch(0, validate=False)
+ self.become_inevitable()
+ self.switch(1, validate=False)
+
+ lib.stmcb_finalizer = finalizer
+ self._finalizer_keepalive = finalizer
+
+ # start a transaction with a finalizing obj
+ self.switch(1)
+ self.start_transaction()
+ lpf = stm_allocate_with_finalizer(16)
+
+ self.push_root(lpf)
+ stm_minor_collect()
+
+
+ self.switch(0)
+ self.start_transaction()
+ stm_set_char(lpo, 'x')
+ self.switch(1)
+ lpf = self.pop_root()
+ # commit this TX, start a new one, let lpf
+ # die with a major-gc:
+ self.commit_transaction()
+ self.start_transaction()
+ stm_major_collect()
+ # commit and run finalizer in separate TX
+ # that will abort because of a conflict
+ self.commit_transaction()
+
+ self.switch(0, validate=False)
+ assert stm_get_char(lpo) == 'x'
+ # commit the now-inevitable TX and run
+ # the aborted finalizer again
+ self.commit_transaction()
+ self.start_transaction()
+ # should now see the value set by finalizer
+ assert stm_get_char(lpo) == 'a'
More information about the pypy-commit
mailing list