[pypy-svn] r51688 - in pypy/dist/pypy/module/_rawffi: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Feb 20 15:09:29 CET 2008


Author: cfbolz
Date: Wed Feb 20 15:09:29 2008
New Revision: 51688

Modified:
   pypy/dist/pypy/module/_rawffi/interp_rawffi.py
   pypy/dist/pypy/module/_rawffi/structure.py
   pypy/dist/pypy/module/_rawffi/test/test__rawffi.py
   pypy/dist/pypy/module/_rawffi/tracker.py
Log:
add a possibility to have structures automatically free their buffers


Modified: pypy/dist/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/dist/pypy/module/_rawffi/interp_rawffi.py	Wed Feb 20 15:09:29 2008
@@ -214,13 +214,15 @@
     def free(self, space):
         if not self.ll_buffer:
             raise segfault_exception(space, "freeing NULL pointer")
+        self._free()
+    free.unwrap_spec = ['self', ObjSpace]
+
+    def _free(self):
         if tracker.DO_TRACING:
             ll_buf = rffi.cast(rffi.INT, self.ll_buffer)
             tracker.trace_free(ll_buf)
         lltype.free(self.ll_buffer, flavor='raw')
         self.ll_buffer = lltype.nullptr(rffi.VOIDP.TO)
-    free.unwrap_spec = ['self', ObjSpace]
-
 
 def unwrap_truncate_int(TP, space, w_arg):
     if space.is_true(space.isinstance(w_arg, space.w_int)):

Modified: pypy/dist/pypy/module/_rawffi/structure.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/structure.py	(original)
+++ pypy/dist/pypy/module/_rawffi/structure.py	Wed Feb 20 15:09:29 2008
@@ -69,9 +69,21 @@
             raise OperationError(space.w_AttributeError, space.wrap(
                 "C Structure has no attribute %s" % attr))
 
-    def descr_call(self, space):
+    def descr_call(self, space, __args__):
+        args_w, kwargs_w = __args__.unpack()
+        if args_w:
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("too many arguments"))
+        autofree = False
+        if 'autofree' in kwargs_w:
+            autofree = space.is_true(kwargs_w.pop('autofree'))
+        if len(kwargs_w):
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("unknown keyword argument"))
+        if autofree:
+            return space.wrap(W_StructureInstanceAutoFree(space, self))
         return space.wrap(W_StructureInstance(space, self, 0))
-    descr_call.unwrap_spec = ['self', ObjSpace]
+    descr_call.unwrap_spec = ['self', ObjSpace, Arguments]
 
     def descr_repr(self, space):
         fieldnames = ' '.join(["'%s'" % name for name, _ in self.fields])
@@ -169,3 +181,11 @@
 )
 W_StructureInstance.typedef.acceptable_as_base_class = False
 
+class W_StructureInstanceAutoFree(W_StructureInstance):
+    def __init__(self, space, shape):
+        W_StructureInstance.__init__(self, space, shape, 0)
+
+    def __del__(self):
+        if self.ll_buffer:
+            self._free()
+

Modified: pypy/dist/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/dist/pypy/module/_rawffi/test/test__rawffi.py	Wed Feb 20 15:09:29 2008
@@ -4,6 +4,7 @@
 from pypy.translator.tool.cbuild import compile_c_module, \
      ExternalCompilationInfo
 from pypy.module._rawffi.interp_rawffi import TYPEMAP
+from pypy.module._rawffi.tracker import Tracker
 
 import os, sys, py
 
@@ -610,3 +611,28 @@
         a.free()
         raises(_rawffi.SegfaultException, a.__getitem__, 3)
         raises(_rawffi.SegfaultException, a.__setitem__, 3, 3)
+
+
+class AppTestAutoFree:
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=('_rawffi', 'struct'))
+        cls.space = space
+        cls.w_sizes_and_alignments = space.wrap(dict(
+            [(k, (v.c_size, v.c_alignment)) for k,v in TYPEMAP.iteritems()]))
+        Tracker.DO_TRACING = True
+
+    def test_structure_autofree(self):
+        import gc, _rawffi
+        S = _rawffi.Structure([('x', 'i')])
+        oldnum = _rawffi._num_of_allocated_objects()
+        s = S(autofree=True)
+        s.x = 3
+        s = None
+        gc.collect()
+        gc.collect()
+        gc.collect()
+        assert oldnum == _rawffi._num_of_allocated_objects()
+
+    def teardown_class(cls):
+        Tracker.DO_TRACING = False
+

Modified: pypy/dist/pypy/module/_rawffi/tracker.py
==============================================================================
--- pypy/dist/pypy/module/_rawffi/tracker.py	(original)
+++ pypy/dist/pypy/module/_rawffi/tracker.py	Wed Feb 20 15:09:29 2008
@@ -12,7 +12,7 @@
         self.alloced = {}
 
     def trace_allocation(self, address, obj):
-        self.alloced[address] = obj
+        self.alloced[address] = True
 
     def trace_free(self, address):
         del self.alloced[address]



More information about the Pypy-commit mailing list