Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r67923:b1b2e7994eda Date: 2013-11-10 09:05 +0000 http://bitbucket.org/pypy/pypy/changeset/b1b2e7994eda/
Log: Import cffi/1e317570f885 diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -129,11 +129,9 @@ cdecl = cdecl.encode('ascii') # type = self._parser.parse_type(cdecl) - if hasattr(type, 'as_function_pointer'): - really_a_function_type = True + really_a_function_type = type.is_raw_function + if really_a_function_type: type = type.as_function_pointer() - else: - really_a_function_type = False btype = self._get_cached_btype(type) result = btype, really_a_function_type self._parsed_types[key] = result diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py --- a/lib_pypy/cffi/model.py +++ b/lib_pypy/cffi/model.py @@ -1,7 +1,10 @@ import weakref +from .lock import allocate_lock + class BaseTypeByIdentity(object): is_array_type = False + is_raw_function = False def get_c_name(self, replace_with='', context='a C file'): result = self.c_name_with_marker @@ -146,6 +149,7 @@ # a function, but not a pointer-to-function. The backend has no # notion of such a type; it's used temporarily by parsing. _base_pattern = '(&)(%s)' + is_raw_function = True def build_backend_type(self, ffi, finishlist): from . import api @@ -212,8 +216,10 @@ self.item = item self.length = length # - if length is None or length == '...': + if length is None: brackets = '&[]' + elif length == '...': + brackets = '&[/*...*/]' else: brackets = '&[%d]' % length self.c_name_with_marker = ( @@ -448,6 +454,9 @@ tp = StructType(structname, None, None, None) return NamedPointerType(tp, name) + +global_lock = allocate_lock() + def global_cache(srctype, ffi, funcname, *args, **kwds): key = kwds.pop('key', (funcname, args)) assert not kwds @@ -468,8 +477,17 @@ res = getattr(ffi._backend, funcname)(*args) except NotImplementedError as e: raise NotImplementedError("%r: %s" % (srctype, e)) - ffi._backend.__typecache[key] = res - return res + # 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: + 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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit