[pypy-commit] pypy errno-again: more

arigo noreply at buildbot.pypy.org
Wed Jan 14 17:32:14 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: errno-again
Changeset: r75326:f3a322ed81fc
Date: 2015-01-14 17:31 +0100
http://bitbucket.org/pypy/pypy/changeset/f3a322ed81fc/

Log:	more

diff --git a/rpython/rtyper/lltypesystem/module/ll_math.py b/rpython/rtyper/lltypesystem/module/ll_math.py
--- a/rpython/rtyper/lltypesystem/module/ll_math.py
+++ b/rpython/rtyper/lltypesystem/module/ll_math.py
@@ -58,11 +58,15 @@
 math_atan2 = llexternal('atan2', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
 math_frexp = llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE)
 math_modf  = llexternal('modf',  [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE)
-math_ldexp = llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE)
-math_pow   = llexternal('pow', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
-math_fmod  = llexternal('fmod',  [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
+math_ldexp = llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE,
+                        save_err=rffi.RFFI_FULL_ERRNO_ZERO)
+math_pow   = llexternal('pow', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE,
+                        save_err=rffi.RFFI_FULL_ERRNO_ZERO)
+math_fmod  = llexternal('fmod',  [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE,
+                        save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 math_hypot = llexternal(UNDERSCORE_ON_WIN32 + 'hypot',
-                        [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
+                        [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE,
+                        save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE, elidable_function=True)
 math_sqrt = llexternal('sqrt', [rffi.DOUBLE], rffi.DOUBLE)
 math_sin = llexternal('sin', [rffi.DOUBLE], rffi.DOUBLE, elidable_function=True)
@@ -80,9 +84,6 @@
 ERANGE = errno.ERANGE
 EDOM   = errno.EDOM
 
-def _error_reset():
-    rposix.set_errno(0)
-
 def _likely_raise(errno, x):
     """Call this with errno != 0.  It usually raises the proper RPython
     exception, but may also just ignore it and return in case of underflow.
@@ -209,9 +210,8 @@
         r = math_copysign(0.0, x)
         errno = 0
     else:
-        _error_reset()
         r = math_ldexp(x, exp)
-        errno = rposix.get_errno()
+        errno = rposix.get_saved_errno()
         if isinf(r):
             errno = ERANGE
     if errno:
@@ -241,9 +241,8 @@
     if isinf(y) and isfinite(x):
         return x
 
-    _error_reset()
     r = math_fmod(x, y)
-    errno = rposix.get_errno()
+    errno = rposix.get_saved_errno()
     if isnan(r):
         if isnan(x) or isnan(y):
             errno = 0
@@ -261,9 +260,8 @@
     if isinf(y):
         return math_fabs(y)
 
-    _error_reset()
     r = math_hypot(x, y)
-    errno = rposix.get_errno()
+    errno = rposix.get_saved_errno()
     if not isfinite(r):
         if isnan(r):
             if isnan(x) or isnan(y):
@@ -319,9 +317,8 @@
         else:
             return 0.0
 
-    _error_reset()
     r = math_pow(x, y)
-    errno = rposix.get_errno()
+    errno = rposix.get_saved_errno()
     if not isfinite(r):
         if isnan(r):
             # a NaN result should arise only from (-ve)**(finite non-integer)
@@ -382,15 +379,16 @@
 
 def new_unary_math_function(name, can_overflow, c99):
     if sys.platform == 'win32' and c99:
-        c_func = math_llexternal(name, [rffi.DOUBLE], rffi.DOUBLE)
+        c_func = math_llexternal(name, [rffi.DOUBLE], rffi.DOUBLE,
+                                 save_err=rffi.RFFI_FULL_ERRNO_ZERO)
     else:
-        c_func = llexternal(name, [rffi.DOUBLE], rffi.DOUBLE)
+        c_func = llexternal(name, [rffi.DOUBLE], rffi.DOUBLE,
+                            save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 
     def ll_math(x):
-        _error_reset()
         r = c_func(x)
         # Error checking fun.  Copied from CPython 2.6
-        errno = rposix.get_errno()
+        errno = rposix.get_saved_errno()
         if not isfinite(r):
             if isnan(r):
                 if isnan(x):
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
@@ -59,11 +59,13 @@
         hop.exception_cannot_occur()
         return hop.inputconst(lltype.Bool, hop.s_result.const)
 
-RFFI_SAVE_ERRNO          = 1
-RFFI_READSAVED_ERRNO     = 2
+RFFI_SAVE_ERRNO          = 1     # save the real errno after the call
+RFFI_READSAVED_ERRNO     = 2     # copy saved errno into real errno before call
+RFFI_ZERO_ERRNO_BEFORE   = 4     # copy the value 0 into real errno before call
 RFFI_FULL_ERRNO          = RFFI_SAVE_ERRNO | RFFI_READSAVED_ERRNO
-RFFI_SAVE_LASTERROR      = 4
-RFFI_READSAVED_LASTERROR = 8
+RFFI_FULL_ERRNO_ZERO     = RFFI_SAVE_ERRNO | RFFI_ZERO_ERRNO_BEFORE
+RFFI_SAVE_LASTERROR      = 8
+RFFI_READSAVED_LASTERROR = 16
 RFFI_FULL_LASTERROR      = RFFI_SAVE_LASTERROR | RFFI_READSAVED_LASTERROR
 RFFI_ERR_NONE            = 0
 RFFI_ERR_ALL             = RFFI_FULL_ERRNO | RFFI_FULL_LASTERROR
@@ -157,7 +159,9 @@
 
     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.
@@ -170,7 +174,7 @@
         # argument to wrapper(), if any (e.g. RPython strings).
 
         source = py.code.Source("""
-            if %(errno_before)s or %(errno_after)s:
+            if %(errno_any)s:
                 from rpython.rlib import rposix, rthread
 
             def call_external_function(%(argnames)s):
@@ -181,6 +185,8 @@
                 # 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)
                 #
                 res = funcptr(%(argnames)s)
                 #
@@ -194,6 +200,7 @@
         """ % locals())
         miniglobals = {'aroundstate': aroundstate,
                        'funcptr':     funcptr,
+                       'int_zero':    cast(INT, 0),
                        '__name__':    __name__, # for module name propagation
                        }
         exec source.compile() in miniglobals
@@ -221,13 +228,15 @@
             # ...well, unless it's a macro, in which case we still have
             # to hide it from the JIT...
             source = py.code.Source("""
-                if %(errno_before)s or %(errno_after)s:
+                if %(errno_any)s:
                     from rpython.rlib import rposix, rthread
 
                 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)
                     #
                     res = funcptr(%(argnames)s)
                     #
@@ -238,6 +247,7 @@
                     return res
             """ % locals())
             miniglobals = {'funcptr':     funcptr,
+                           'int_zero':    cast(INT, 0),
                            '__name__':    __name__,
                            }
             exec source.compile() in miniglobals
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -630,10 +630,9 @@
     @registering_if(os, 'sysconf')
     def register_os_sysconf(self):
         c_sysconf = self.llexternal('sysconf', [rffi.INT], rffi.LONG,
-                                    save_err=rffi.RFFI_FULL_ERRNO)
+                                    save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 
         def sysconf_llimpl(i):
-            rposix.set_saved_errno(0)
             res = c_sysconf(i)
             if res == -1:
                 errno = rposix.get_saved_errno()
@@ -646,10 +645,9 @@
     def register_os_fpathconf(self):
         c_fpathconf = self.llexternal('fpathconf',
                                       [rffi.INT, rffi.INT], rffi.LONG,
-                                      save_err=rffi.RFFI_FULL_ERRNO)
+                                      save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 
         def fpathconf_llimpl(fd, i):
-            rposix.set_saved_errno(0)
             res = c_fpathconf(fd, i)
             if res == -1:
                 errno = rposix.get_saved_errno()
@@ -663,10 +661,9 @@
     def register_os_pathconf(self):
         c_pathconf = self.llexternal('pathconf',
                                      [rffi.CCHARP, rffi.INT], rffi.LONG,
-                                     save_err=rffi.RFFI_FULL_ERRNO)
+                                     save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 
         def pathconf_llimpl(path, i):
-            rposix.set_saved_errno(0)
             res = c_pathconf(path, i)
             if res == -1:
                 errno = rposix.get_saved_errno()
@@ -680,10 +677,9 @@
     def register_os_confstr(self):
         c_confstr = self.llexternal('confstr', [rffi.INT, rffi.CCHARP,
                                                 rffi.SIZE_T], rffi.SIZE_T,
-                                                save_err=rffi.RFFI_FULL_ERRNO)
+                                    save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 
         def confstr_llimpl(i):
-            rposix.set_saved_errno(0)
             n = c_confstr(i, lltype.nullptr(rffi.CCHARP.TO), 0)
             n = rffi.cast(lltype.Signed, n)
             if n > 0:
@@ -1305,7 +1301,7 @@
             # dirent struct (which depends on defines)
             os_readdir = self.llexternal('readdir', [DIRP], DIRENTP,
                                          compilation_info=compilation_info,
-                                         save_err=rffi.RFFI_FULL_ERRNO,
+                                         save_err=rffi.RFFI_FULL_ERRNO_ZERO,
                                          macro=True)
             os_closedir = self.llexternal('closedir', [DIRP], rffi.INT,
                                           compilation_info=compilation_info)
@@ -1316,7 +1312,6 @@
                     raise OSError(rposix.get_saved_errno(), "os_opendir failed")
                 result = []
                 while True:
-                    rposix.set_saved_errno(0)
                     direntp = os_readdir(dirp)
                     if not direntp:
                         error = rposix.get_saved_errno()
@@ -1711,7 +1706,7 @@
         def mknod_llimpl(path, mode, dev):
             res = rffi.cast(lltype.Signed, os_mknod(path, mode, dev))
             if res < 0:
-                raise OSError(rposix.get_sved_errno(), "os_mknod failed")
+                raise OSError(rposix.get_saved_errno(), "os_mknod failed")
 
         return extdef([traits.str0, int, int], s_None, llimpl=mknod_llimpl,
                       export_name=traits.ll_os_name('mknod'))
@@ -1874,13 +1869,12 @@
     @registering_if(os, 'nice')
     def register_os_nice(self):
         os_nice = self.llexternal('nice', [rffi.INT], rffi.INT,
-                                  save_err=rffi.RFFI_FULL_ERRNO)
+                                  save_err=rffi.RFFI_FULL_ERRNO_ZERO)
 
         def nice_llimpl(inc):
             # Assume that the system provides a standard-compliant version
             # of nice() that returns the new priority.  Nowadays, FreeBSD
             # might be the last major non-compliant system (xxx check me).
-            rposix.set_saved_errno(0)
             res = rffi.cast(lltype.Signed, os_nice(inc))
             if res == -1:
                 err = rposix.get_saved_errno()
diff --git a/rpython/rtyper/module/ll_time.py b/rpython/rtyper/module/ll_time.py
--- a/rpython/rtyper/module/ll_time.py
+++ b/rpython/rtyper/module/ll_time.py
@@ -218,7 +218,8 @@
         else:
             c_select = self.llexternal('select', [rffi.INT, rffi.VOIDP,
                                                   rffi.VOIDP, rffi.VOIDP,
-                                                  self.TIMEVALP], rffi.INT)
+                                                  self.TIMEVALP], rffi.INT,
+                                       save_err=rffi.RFFI_SAVE_ERRNO)
             def time_sleep_llimpl(secs):
                 void = lltype.nullptr(rffi.VOIDP.TO)
                 t = lltype.malloc(self.TIMEVAL, flavor='raw')
@@ -228,9 +229,9 @@
                     rffi.setintfield(t, 'c_tv_usec', int(frac*1000000.0))
 
                     if rffi.cast(rffi.LONG, c_select(0, void, void, void, t)) != 0:
-                        errno = rposix.get_errno()
+                        errno = rposix.get_saved_errno()
                         if errno != EINTR:
-                            raise OSError(rposix.get_errno(), "Select failed")
+                            raise OSError(errno, "Select failed")
                 finally:
                     lltype.free(t, flavor='raw')
 


More information about the pypy-commit mailing list