Author: Amaury Forgeot d'Arc <amaur...@gmail.com>
Branch: 
Changeset: r2680:c9b855645ce9
Date: 2016-04-23 10:02 +0200
http://bitbucket.org/cffi/cffi/changeset/c9b855645ce9/

Log:    Implement backend.gcp() for the ctypes backend, and remove
        gc_weakref.

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -397,20 +397,7 @@
         data.  Later, when this new cdata object is garbage-collected,
         'destructor(old_cdata_object)' will be called.
         """
-        try:
-            gcp = self._backend.gcp
-        except AttributeError:
-            pass
-        else:
-            return gcp(cdata, destructor)
-        #
-        with self._lock:
-            try:
-                gc_weakrefs = self.gc_weakrefs
-            except AttributeError:
-                from .gc_weakref import GcWeakrefs
-                gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
-            return gc_weakrefs.build(cdata, destructor)
+        return self._backend.gcp(cdata, destructor)
 
     def _get_cached_btype(self, type):
         assert self._lock.acquire(False) is False
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -993,6 +993,21 @@
         assert onerror is None   # XXX not implemented
         return BType(source, error)
 
+    def gcp(self, cdata, destructor):
+        BType = self.typeof(cdata)
+        try:
+            gcp_type = BType._gcp_type
+        except AttributeError:
+            class CTypesDataGcp(BType):
+                __slots__ = ['_orig', '_destructor']
+                def __del__(self):
+                    self._destructor(self._orig)
+            gcp_type = BType._gcp_type = CTypesDataGcp
+        new_cdata = self.cast(gcp_type, cdata)
+        new_cdata._orig = cdata
+        new_cdata._destructor = destructor
+        return new_cdata
+
     typeof = type
 
     def getcname(self, BType, replace_with):
diff --git a/cffi/gc_weakref.py b/cffi/gc_weakref.py
deleted file mode 100644
--- a/cffi/gc_weakref.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from weakref import ref
-
-
-class GcWeakrefs(object):
-    def __init__(self, ffi):
-        self.ffi = ffi
-        self.data = {}
-
-    def build(self, cdata, destructor):
-        # make a new cdata of the same type as the original one
-        new_cdata = self.ffi.cast(self.ffi._backend.typeof(cdata), cdata)
-        #
-        def remove(key):
-            # careful, this function is not protected by any lock
-            old_key = self.data.pop(index)
-            assert old_key is key
-            destructor(cdata)
-        #
-        key = ref(new_cdata, remove)
-        index = object()
-        self.data[index] = key
-        return new_cdata
diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py
--- a/testing/cffi0/backend_tests.py
+++ b/testing/cffi0/backend_tests.py
@@ -1524,19 +1524,14 @@
 
     def test_gc_finite_list(self):
         ffi = FFI(backend=self.Backend())
-        public = not hasattr(ffi._backend, 'gcp')
         p = ffi.new("int *", 123)
         keepalive = []
         for i in range(10):
             keepalive.append(ffi.gc(p, lambda p: None))
-            if public:
-                assert len(ffi.gc_weakrefs.data) == i + 1
         del keepalive[:]
         import gc; gc.collect(); gc.collect()
         for i in range(10):
             keepalive.append(ffi.gc(p, lambda p: None))
-        if public:
-            assert len(ffi.gc_weakrefs.data) == 10
 
     def test_CData_CType(self):
         ffi = FFI(backend=self.Backend())
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to