summaryrefslogtreecommitdiff
path: root/cffi/model.py
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2013-11-10 09:18:59 +0100
committerArmin Rigo <arigo@tunes.org>2013-11-10 09:18:59 +0100
commitb465d69aa9746b34aad9f1dd7ac3ef0c21f3820a (patch)
treebc687ecd9cb30e38099111ac4d4b6f628ad29d4c /cffi/model.py
parent870245264d58dbdecd3ae4788365174716740072 (diff)
downloadcffi-b465d69aa9746b34aad9f1dd7ac3ef0c21f3820a.tar.gz
Bah, setdefault() is not atomic on WeakValueDictionary.
Diffstat (limited to 'cffi/model.py')
-rw-r--r--cffi/model.py11
1 files changed, 9 insertions, 2 deletions
diff --git a/cffi/model.py b/cffi/model.py
index 15e5658..b6d9ebd 100644
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -1,4 +1,6 @@
import weakref
+from .lock import allocate_lock
+
class BaseTypeByIdentity(object):
is_array_type = False
@@ -452,8 +454,10 @@ def unknown_ptr_type(name, structname=None):
tp = StructType(structname, None, None, None)
return NamedPointerType(tp, name)
+
+global_lock = allocate_lock()
+
def global_cache(srctype, ffi, funcname, *args, **kwds):
- # NB. multithread: careful code that should work without an explicit lock
key = kwds.pop('key', (funcname, args))
assert not kwds
try:
@@ -473,7 +477,10 @@ def global_cache(srctype, ffi, funcname, *args, **kwds):
res = getattr(ffi._backend, funcname)(*args)
except NotImplementedError as e:
raise NotImplementedError("%r: %s" % (srctype, e))
- return ffi._backend.__typecache.setdefault(key, res)
+ # note that setdefault() on WeakValueDictionary is not atomic,
+ # which means that we have to use a lock too
+ with global_lock:
+ return ffi._backend.__typecache.setdefault(key, res)
def pointer_cache(ffi, BType):
return global_cache('?', ffi, 'new_pointer_type', BType)