diff options
author | Armin Rigo <arigo@tunes.org> | 2016-09-03 20:04:31 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2016-09-03 20:04:31 +0200 |
commit | d114114c36d8ffdb73321b810c8732fefdf80604 (patch) | |
tree | 9ce8d6fa3bbb422608b1759b4ccaf6fb045b1bb4 /cffi/backend_ctypes.py | |
parent | 95559d143194836d781945e40b8ff0914b684315 (diff) | |
download | cffi-d114114c36d8ffdb73321b810c8732fefdf80604.tar.gz |
Issue #282: probable test and fix
Diffstat (limited to 'cffi/backend_ctypes.py')
-rw-r--r-- | cffi/backend_ctypes.py | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py index b2579b3..ed2e6cd 100644 --- a/cffi/backend_ctypes.py +++ b/cffi/backend_ctypes.py @@ -997,29 +997,35 @@ class CTypesBackend(object): assert onerror is None # XXX not implemented return BType(source, error) + _weakref_cache_ref = None + def gcp(self, cdata, destructor): - BType = self.typeof(cdata) + if self._weakref_cache_ref is None: + import weakref + class MyRef(weakref.ref): + def __eq__(self, other): + return self() is other() + def __ne__(self, other): + return self() is not other() + self._weakref_cache_ref = {}, MyRef + weak_cache, MyRef = self._weakref_cache_ref if destructor is None: - if not (hasattr(BType, '_gcp_type') and - BType._gcp_type is BType): + try: + del weak_cache[MyRef(cdata)] + except KeyError: raise TypeError("Can remove destructor only on a object " "previously returned by ffi.gc()") - cdata._destructor = None return None - try: - gcp_type = BType._gcp_type - except AttributeError: - class CTypesDataGcp(BType): - __slots__ = ['_orig', '_destructor'] - def __del__(self): - if self._destructor is not None: - 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 + def remove(k): + cdata, destructor = weak_cache.pop(k, (None, None)) + if destructor is not None: + destructor(cdata) + + new_cdata = self.cast(self.typeof(cdata), cdata) + assert new_cdata is not cdata + weak_cache[MyRef(new_cdata, remove)] = (cdata, destructor) return new_cdata typeof = type |