diff options
author | Armin Rigo <arigo@tunes.org> | 2013-11-10 10:03:00 +0100 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2013-11-10 10:03:00 +0100 |
commit | 7de9b401b702fd848b9a9731324915582c7fbcf5 (patch) | |
tree | 0b5a413b9990c79feb9114a35d1ba86937436909 | |
parent | b465d69aa9746b34aad9f1dd7ac3ef0c21f3820a (diff) | |
download | cffi-7de9b401b702fd848b9a9731324915582c7fbcf5.tar.gz |
Due to a CPython bug, we cannot use setdefault() here
-rw-r--r-- | cffi/model.py | 13 |
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) |