Author: Armin Rigo <[email protected]>
Branch: finalizer
Changeset: r1466:d5a95166f741
Date: 2014-10-06 18:23 +0200
http://bitbucket.org/pypy/stmgc/changeset/d5a95166f741/

Log:    Write down some rules, and figured out that there is a problem with
        light finalizers too

diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
--- a/c7/stm/finalizer.c
+++ b/c7/stm/finalizer.c
@@ -1,6 +1,7 @@
 
 
 void (*stmcb_light_finalizer)(object_t *);
+void (*stmcb_finalizer)(object_t *);
 
 void stm_enable_light_finalizer(object_t *obj)
 {
@@ -10,6 +11,11 @@
         LIST_APPEND(STM_PSEGMENT->old_objects_with_light_finalizers, obj);
 }
 
+object_t *stm_allocate_with_finalizer(ssize_t size_rounded_up)
+{
+    abort();  // NOT IMPLEMENTED
+}
+
 static void deal_with_young_objects_with_finalizers(void)
 {
     /* for light finalizers */
@@ -47,7 +53,7 @@
             object_t* obj = (object_t *)list_item(lst, i);
             if (!mark_visited_test(obj)) {
                 /* not marked: object dies */
-                /* we're calling the light finalizer is a random thread,
+                /* we're calling the light finalizer in a random thread,
                    but it should work, because it was dead already at the
                    start of that thread's transaction, so any thread should
                    see the same, old content */
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -511,6 +511,18 @@
 void (*stmcb_light_finalizer)(object_t *);
 void stm_enable_light_finalizer(object_t *);
 
+/* Support for regular finalizers.  Unreachable objects with
+   finalizers are kept alive, as well as everything they point to, and
+   stmcb_finalizer() is called after the major GC.  If there are
+   several objects with finalizers that reference each other in a
+   well-defined order (i.e. there are no cycles), then they are
+   finalized in order from outermost to innermost (i.e.  starting with
+   the ones that are unreachable even from others).  The finalizer is
+   called in a random thread, except for objects that have been
+   created by the current transaction in a thread; in that case, only
+   that thread can call the finalizer. */
+void (*stmcb_finalizer)(object_t *);
+object_t *stm_allocate_with_finalizer(ssize_t size_rounded_up);
 
 /* ==================== END ==================== */
 
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -31,6 +31,7 @@
 /*void stm_write(object_t *obj); use _checked_stm_write() instead */
 object_t *stm_allocate(ssize_t size_rounded_up);
 object_t *stm_allocate_weakref(ssize_t size_rounded_up);
+object_t *stm_allocate_with_finalizer(ssize_t size_rounded_up);
 object_t *_stm_allocate_old(ssize_t size_rounded_up);
 
 /*void stm_write_card(); use _checked_stm_write_card() instead */
diff --git a/c7/test/test_finalizer.py b/c7/test/test_finalizer.py
--- a/c7/test/test_finalizer.py
+++ b/c7/test/test_finalizer.py
@@ -73,3 +73,32 @@
         stm_major_collect()
         self.commit_transaction()
         self.expect_finalized([])
+
+
+class TestRegularFinalizer(BaseTest):
+
+    def setup_method(self, meth):
+        BaseTest.setup_method(self, meth)
+        #
+        @ffi.callback("void(object_t *)")
+        def finalizer(obj):
+            self.finalizers_called.append(obj)
+        self.finalizers_called = []
+        lib.stmcb_finalizer = finalizer
+        self._finalizer_keepalive = finalizer
+
+    def expect_finalized(self, objs):
+        assert self.finalizers_called == objs
+        self.finalizers_called = []
+
+    def test_no_finalizer(self):
+        self.start_transaction()
+        lp1 = stm_allocate(48)
+        stm_major_collect()
+        self.expect_finalized([])
+
+    def test_no_finalizer_in_minor_collection(self):
+        self.start_transaction()
+        lp1 = stm_allocate_with_finalizer(48)
+        stm_minor_collect()
+        self.expect_finalized([])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to