[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