Author: Armin Rigo <[email protected]>
Branch: gc-del-3
Changeset: r84186:6746f707cca8
Date: 2016-05-04 15:48 +0200
http://bitbucket.org/pypy/pypy/changeset/6746f707cca8/

Log:    Check that finalizer_trigger() doesn't cause GIL-releasing
        operations, like we check in the old-style non-light __del__().

diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -501,6 +501,12 @@
         return self.bookkeeper.immutablevalue(fq._fq_tag)
 
     def specialize_call(self, hop):
+        from rpython.rtyper.rclass import InstanceRepr
+        translator = hop.rtyper.annotator.translator
+        fq = hop.args_s[0].const
+        graph = translator._graphof(fq.finalizer_trigger.im_func)
+        InstanceRepr.check_graph_of_del_does_not_call_too_much(hop.rtyper,
+                                                               graph)
         hop.exception_cannot_occur()
         return hop.inputconst(lltype.Signed, hop.s_result.const)
 
diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py
--- a/rpython/rlib/test/test_rgc.py
+++ b/rpython/rlib/test/test_rgc.py
@@ -1,4 +1,5 @@
 from rpython.rtyper.test.test_llinterp import gengraph, interpret
+from rpython.rtyper.error import TyperError
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rlib import rgc # Force registration of gc.collect
 import gc
@@ -265,7 +266,7 @@
         self.x = x
 
 class SimpleFQ(rgc.FinalizerQueue):
-    base_class = T_Root
+    Class = T_Root
     _triggered = 0
     def finalizer_trigger(self):
         self._triggered += 1
@@ -367,3 +368,21 @@
         assert fq.next_dead() is None
         assert deleted == {(1, 42): 1}
         assert fq._triggered == 1
+
+    def test_finalizer_trigger_calls_too_much(self):
+        from rpython.rtyper.lltypesystem import lltype, rffi
+        external_func = rffi.llexternal("foo", [], lltype.Void)
+        # ^^^ with release_gil=True
+        class X(object):
+            pass
+        class FQ(rgc.FinalizerQueue):
+            Class = X
+            def finalizer_trigger(self):
+                external_func()
+        fq = FQ()
+        def f():
+            x = X()
+            fq.register_finalizer(x)
+
+        e = py.test.raises(TyperError, gengraph, f, [])
+        assert str(e.value).startswith('the RPython-level __del__() method in')
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -587,7 +587,8 @@
                 assert len(s_func.descriptions) == 1
                 funcdesc, = s_func.descriptions
                 graph = funcdesc.getuniquegraph()
-                self.check_graph_of_del_does_not_call_too_much(graph)
+                self.check_graph_of_del_does_not_call_too_much(self.rtyper,
+                                                               graph)
                 FUNCTYPE = FuncType([Ptr(source_repr.object_type)], Void)
                 destrptr = functionptr(FUNCTYPE, graph.name,
                                        graph=graph,
@@ -859,7 +860,8 @@
     def can_ll_be_null(self, s_value):
         return s_value.can_be_none()
 
-    def check_graph_of_del_does_not_call_too_much(self, graph):
+    @staticmethod
+    def check_graph_of_del_does_not_call_too_much(rtyper, graph):
         # RPython-level __del__() methods should not do "too much".
         # In the PyPy Python interpreter, they usually do simple things
         # like file.__del__() closing the file descriptor; or if they
@@ -872,7 +874,7 @@
         #
         # XXX wrong complexity, but good enough because the set of
         # reachable graphs should be small
-        callgraph = self.rtyper.annotator.translator.callgraph.values()
+        callgraph = rtyper.annotator.translator.callgraph.values()
         seen = {graph: None}
         while True:
             oldlength = len(seen)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to