summaryrefslogtreecommitdiff
path: root/cffi/model.py
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2013-11-10 10:03:00 +0100
committerArmin Rigo <arigo@tunes.org>2013-11-10 10:03:00 +0100
commit7de9b401b702fd848b9a9731324915582c7fbcf5 (patch)
tree0b5a413b9990c79feb9114a35d1ba86937436909 /cffi/model.py
parentb465d69aa9746b34aad9f1dd7ac3ef0c21f3820a (diff)
downloadcffi-7de9b401b702fd848b9a9731324915582c7fbcf5.tar.gz
Due to a CPython bug, we cannot use setdefault() here
Diffstat (limited to 'cffi/model.py')
-rw-r--r--cffi/model.py13
1 files changed, 10 insertions, 3 deletions
diff --git a/cffi/model.py b/cffi/model.py
index b6d9ebd..45609c2 100644
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -477,10 +477,17 @@ def global_cache(srctype, ffi, funcname, *args, **kwds):
res = getattr(ffi._backend, funcname)(*args)
except NotImplementedError as e:
raise NotImplementedError("%r: %s" % (srctype, e))
- # note that setdefault() on WeakValueDictionary is not atomic,
- # which means that we have to use a lock too
+ # note that setdefault() on WeakValueDictionary is not atomic
+ # and contains a rare bug (http://bugs.python.org/issue19542);
+ # we have to use a lock and do it ourselves
+ cache = ffi._backend.__typecache
with global_lock:
- return ffi._backend.__typecache.setdefault(key, res)
+ res1 = cache.get(key)
+ if res1 is None:
+ cache[key] = res
+ return res
+ else:
+ return res1
def pointer_cache(ffi, BType):
return global_cache('?', ffi, 'new_pointer_type', BType)