Author: Armin Rigo <ar...@tunes.org> Branch: errno-again Changeset: r75345:c247cd8b63fe Date: 2015-01-15 14:42 +0100 http://bitbucket.org/pypy/pypy/changeset/c247cd8b63fe/
Log: Fix _cffi_backend. diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py --- a/pypy/module/_cffi_backend/ccallback.py +++ b/pypy/module/_cffi_backend/ccallback.py @@ -160,7 +160,7 @@ @jit.jit_callback("CFFI") -def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): +def _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): """ Callback specification. ffi_cif - something ffi specific, don't care ll_args - rffi.VOIDPP - pointer to array of pointers to args @@ -168,7 +168,6 @@ ll_userdata - a special structure which holds necessary information (what the real callback is for example), casted to VOIDP """ - e = cerrno.get_real_errno() ll_res = rffi.cast(rffi.CCHARP, ll_res) unique_id = rffi.cast(lltype.Signed, ll_userdata) callback = global_callback_mapping.get(unique_id) @@ -185,12 +184,9 @@ return # must_leave = False - ec = None space = callback.space try: must_leave = space.threadlocals.try_enter_thread(space) - ec = cerrno.get_errno_container(space) - cerrno.save_errno_into(ec, e) extra_line = '' try: w_res = callback.invoke(ll_args) @@ -212,5 +208,8 @@ callback.write_error_return_value(ll_res) if must_leave: space.threadlocals.leave_thread(space) - if ec is not None: - cerrno.restore_errno_from(ec) + +def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata): + cerrno._errno_after(rffi.RFFI_ERR_ALL) + _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata) + cerrno._errno_before(rffi.RFFI_ERR_ALL) diff --git a/pypy/module/_cffi_backend/cerrno.py b/pypy/module/_cffi_backend/cerrno.py --- a/pypy/module/_cffi_backend/cerrno.py +++ b/pypy/module/_cffi_backend/cerrno.py @@ -2,7 +2,6 @@ from rpython.rlib import rposix -from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.gateway import unwrap_spec WIN32 = sys.platform == 'win32' @@ -10,40 +9,21 @@ from rpython.rlib import rwin32 -ExecutionContext._cffi_saved_errno = 0 -ExecutionContext._cffi_saved_LastError = 0 - - -def get_errno_container(space): - return space.getexecutioncontext() - -get_real_errno = rposix.get_errno - - -def restore_errno_from(ec): - if WIN32: - rwin32.SetLastError(ec._cffi_saved_LastError) - rposix.set_errno(ec._cffi_saved_errno) - -def save_errno_into(ec, errno): - ec._cffi_saved_errno = errno - if WIN32: - ec._cffi_saved_LastError = rwin32.GetLastError() - +_errno_before = rposix._errno_before +_errno_after = rposix._errno_after def get_errno(space): - ec = get_errno_container(space) - return space.wrap(ec._cffi_saved_errno) + return space.wrap(rposix.get_saved_errno()) @unwrap_spec(errno=int) def set_errno(space, errno): - ec = get_errno_container(space) - ec._cffi_saved_errno = errno + rposix.set_saved_errno(errno) # ____________________________________________________________ @unwrap_spec(code=int) def getwinerror(space, code=-1): + XXX from rpython.rlib.rwin32 import FormatError if code == -1: ec = get_errno_container(space) diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -155,13 +155,9 @@ # argtype is a pointer type, and w_obj a list/tuple/str mustfree_max_plus_1 = i + 1 - ec = cerrno.get_errno_container(space) - cerrno.restore_errno_from(ec) jit_libffi.jit_ffi_call(cif_descr, rffi.cast(rffi.VOIDP, funcaddr), buffer) - e = cerrno.get_real_errno() - cerrno.save_errno_into(ec, e) resultdata = rffi.ptradd(buffer, cif_descr.exchange_result) w_res = self.ctitem.copy_and_convert_to_object(resultdata) diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -107,6 +107,21 @@ rthread.tlfield_rpy_errno.setraw(rffi.cast(INT, errno)) +def _errno_before(save_err): + if save_err & rffi.RFFI_READSAVED_ERRNO: + from rpython.rlib import rthread + _set_errno(rthread.tlfield_rpy_errno.getraw()) + elif save_err & rffi.RFFI_ZERO_ERRNO_BEFORE: + _set_errno(rffi.cast(rffi.INT, 0)) +_errno_before._always_inline_ = True + +def _errno_after(save_err): + if save_err & rffi.RFFI_SAVE_ERRNO: + from rpython.rlib import rthread + rthread.tlfield_rpy_errno.setraw(_get_errno()) +_errno_after._always_inline_ = True + + if os.name == 'nt': is_valid_fd = jit.dont_look_inside(rffi.llexternal( "_PyVerify_fd", [rffi.INT], rffi.INT, diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -157,12 +157,6 @@ return funcptr - argnames = ', '.join(['a%d' % i for i in range(len(args))]) - errno_before = (save_err & RFFI_READSAVED_ERRNO) != 0 - errno_zero_before = (save_err & RFFI_ZERO_ERRNO_BEFORE) != 0 - errno_after = (save_err & RFFI_SAVE_ERRNO) != 0 - errno_any = errno_before or errno_zero_before or errno_after - if invoke_around_handlers: # The around-handlers are releasing the GIL in a threaded pypy. # We need tons of care to ensure that no GC operation and no @@ -173,34 +167,23 @@ # neither '*args' nor the GC objects originally passed in as # argument to wrapper(), if any (e.g. RPython strings). + argnames = ', '.join(['a%d' % i for i in range(len(args))]) source = py.code.Source(""" - if %(errno_any)s: - from rpython.rlib import rposix, rthread + from rpython.rlib import rposix def call_external_function(%(argnames)s): before = aroundstate.before if before: before() # NB. it is essential that no exception checking occurs here! - # - # restore errno from its saved value - if %(errno_before)s: - rposix._set_errno(rthread.tlfield_rpy_errno.getraw()) - elif %(errno_zero_before)s: - rposix._set_errno(int_zero) - # + rposix._errno_before(%(save_err)d) res = funcptr(%(argnames)s) - # - # save errno away - if %(errno_after)s: - rthread.tlfield_rpy_errno.setraw(rposix._get_errno()) - # + rposix._errno_after(%(save_err)d) after = aroundstate.after if after: after() return res """ % locals()) miniglobals = {'aroundstate': aroundstate, 'funcptr': funcptr, - 'int_zero': cast(INT, 0), '__name__': __name__, # for module name propagation } exec source.compile() in miniglobals @@ -227,27 +210,17 @@ else: # ...well, unless it's a macro, in which case we still have # to hide it from the JIT... + argnames = ', '.join(['a%d' % i for i in range(len(args))]) source = py.code.Source(""" - if %(errno_any)s: - from rpython.rlib import rposix, rthread + from rpython.rlib import rposix def call_external_function(%(argnames)s): - # restore errno from its saved value - if %(errno_before)s: - rposix._set_errno(rthread.tlfield_rpy_errno.getraw()) - elif %(errno_zero_before)s: - rposix._set_errno(int_zero) - # + rposix._errno_before(%(save_err)d) res = funcptr(%(argnames)s) - # - # save errno away - if %(errno_after)s: - rthread.tlfield_rpy_errno.setraw(rposix._get_errno()) - # + rposix._errno_after(%(save_err)d) return res """ % locals()) miniglobals = {'funcptr': funcptr, - 'int_zero': cast(INT, 0), '__name__': __name__, } exec source.compile() in miniglobals _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit