[pypy-commit] pypy errno-again: Fix _cffi_backend.
arigo
noreply at buildbot.pypy.org
Thu Jan 15 14:43:09 CET 2015
Author: Armin Rigo <arigo at 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
More information about the pypy-commit
mailing list