Author: Remi Meier <remi.me...@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' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit