[pypy-commit] cffi release-1.1: Issue #206: the rewrite of gc_weakref was not multithread-safe

arigo noreply at buildbot.pypy.org
Tue Jun 9 12:08:27 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: release-1.1
Changeset: r2175:85e32070b9f7
Date: 2015-06-09 11:29 +0200
http://bitbucket.org/cffi/cffi/changeset/85e32070b9f7/

Log:	Issue #206: the rewrite of gc_weakref was not multithread-safe

diff --git a/cffi/gc_weakref.py b/cffi/gc_weakref.py
--- a/cffi/gc_weakref.py
+++ b/cffi/gc_weakref.py
@@ -4,25 +4,21 @@
 class GcWeakrefs(object):
     def __init__(self, ffi):
         self.ffi = ffi
-        self.data = []
-        self.freelist = None
+        self.data = {}
+        self.nextindex = 0
 
     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):
-            assert self.data[index] is key
-            self.data[index] = self.freelist
-            self.freelist = index
+            # 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 = self.freelist
-        if index is None:
-            index = len(self.data)
-            self.data.append(key)
-        else:
-            self.freelist = self.data[index]
-            self.data[index] = key
+        index = self.nextindex
+        self.nextindex = index + 1     # we're protected by the lock here
+        self.data[index] = key
         return new_cdata


More information about the pypy-commit mailing list