[pypy-commit] pypy errno-again: in-progress
arigo
noreply at buildbot.pypy.org
Wed Jan 14 19:40:47 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: errno-again
Changeset: r75333:73a539098acc
Date: 2015-01-14 19:40 +0100
http://bitbucket.org/pypy/pypy/changeset/73a539098acc/
Log: in-progress
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -486,10 +486,10 @@
w_exception_class=w_exception_class)
wrap_oserror._annspecialcase_ = 'specialize:arg(3)'
-def exception_from_errno(space, w_type):
- from rpython.rlib.rposix import get_errno
+def exception_from_saved_errno(space, w_type):
+ from rpython.rlib.rposix import get_saved_errno
- errno = get_errno()
+ errno = get_saved_errno()
msg = os.strerror(errno)
w_error = space.call_function(w_type, space.wrap(errno), space.wrap(msg))
return OperationError(w_type, w_error)
diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py
--- a/pypy/module/__pypy__/interp_time.py
+++ b/pypy/module/__pypy__/interp_time.py
@@ -1,7 +1,7 @@
from __future__ import with_statement
import sys
-from pypy.interpreter.error import exception_from_errno
+from pypy.interpreter.error import exception_from_saved_errno
from pypy.interpreter.gateway import unwrap_spec
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rtyper.tool import rffi_platform
@@ -48,11 +48,13 @@
c_clock_gettime = rffi.llexternal("clock_gettime",
[lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
- compilation_info=CConfig._compilation_info_, releasegil=False
+ compilation_info=CConfig._compilation_info_, releasegil=False,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
c_clock_getres = rffi.llexternal("clock_getres",
[lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
- compilation_info=CConfig._compilation_info_, releasegil=False
+ compilation_info=CConfig._compilation_info_, releasegil=False,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
@unwrap_spec(clk_id="c_int")
@@ -60,7 +62,7 @@
with lltype.scoped_alloc(TIMESPEC) as tp:
ret = c_clock_gettime(clk_id, tp)
if ret != 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
return space.wrap(int(tp.c_tv_sec) + 1e-9 * int(tp.c_tv_nsec))
@unwrap_spec(clk_id="c_int")
@@ -68,5 +70,5 @@
with lltype.scoped_alloc(TIMESPEC) as tp:
ret = c_clock_getres(clk_id, tp)
if ret != 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
return space.wrap(int(tp.c_tv_sec) + 1e-9 * int(tp.c_tv_nsec))
diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -613,10 +613,10 @@
return space.wrap(W_CDLL(space, name, cdll))
def get_errno(space):
- return space.wrap(rposix.get_errno())
+ return space.wrap(rposix.get_saved_errno())
def set_errno(space, w_errno):
- rposix.set_errno(space.int_w(w_errno))
+ rposix.set_saved_errno(space.int_w(w_errno))
if sys.platform == 'win32':
def get_last_error(space):
diff --git a/pypy/module/fcntl/interp_fcntl.py b/pypy/module/fcntl/interp_fcntl.py
--- a/pypy/module/fcntl/interp_fcntl.py
+++ b/pypy/module/fcntl/interp_fcntl.py
@@ -59,18 +59,24 @@
return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_)
_flock = lltype.Ptr(cConfig.flock)
-fcntl_int = external('fcntl', [rffi.INT, rffi.INT, rffi.INT], rffi.INT)
-fcntl_str = external('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP], rffi.INT)
-fcntl_flock = external('fcntl', [rffi.INT, rffi.INT, _flock], rffi.INT)
-ioctl_int = external('ioctl', [rffi.INT, rffi.UINT, rffi.INT], rffi.INT)
-ioctl_str = external('ioctl', [rffi.INT, rffi.UINT, rffi.CCHARP], rffi.INT)
+fcntl_int = external('fcntl', [rffi.INT, rffi.INT, rffi.INT], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+fcntl_str = external('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+fcntl_flock = external('fcntl', [rffi.INT, rffi.INT, _flock], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ioctl_int = external('ioctl', [rffi.INT, rffi.UINT, rffi.INT], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ioctl_str = external('ioctl', [rffi.INT, rffi.UINT, rffi.CCHARP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
has_flock = cConfig.has_flock
if has_flock:
- c_flock = external('flock', [rffi.INT, rffi.INT], rffi.INT)
+ c_flock = external('flock', [rffi.INT, rffi.INT], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
def _get_error(space, funcname):
- errno = rposix.get_errno()
+ errno = rposix.get_saved_errno()
return wrap_oserror(space, OSError(errno, funcname),
exception_name = 'w_IOError')
diff --git a/pypy/module/select/interp_epoll.py b/pypy/module/select/interp_epoll.py
--- a/pypy/module/select/interp_epoll.py
+++ b/pypy/module/select/interp_epoll.py
@@ -4,12 +4,13 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.gateway import interp2app, unwrap_spec
-from pypy.interpreter.error import OperationError, exception_from_errno, oefmt
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import exception_from_saved_errno
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper.tool import rffi_platform
from rpython.rlib._rsocket_rffi import socketclose, FD_SETSIZE
-from rpython.rlib.rposix import get_errno
+from rpython.rlib.rposix import get_saved_errno
from rpython.rlib.rarithmetic import intmask
from rpython.translator.tool.cbuild import ExternalCompilationInfo
@@ -53,19 +54,22 @@
EPOLL_CTL_DEL = cconfig["EPOLL_CTL_DEL"]
epoll_create = rffi.llexternal(
- "epoll_create", [rffi.INT], rffi.INT, compilation_info=eci
+ "epoll_create", [rffi.INT], rffi.INT, compilation_info=eci,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
epoll_ctl = rffi.llexternal(
"epoll_ctl",
[rffi.INT, rffi.INT, rffi.INT, lltype.Ptr(epoll_event)],
rffi.INT,
- compilation_info=eci
+ compilation_info=eci,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
epoll_wait = rffi.llexternal(
"epoll_wait",
[rffi.INT, rffi.CArrayPtr(epoll_event), rffi.INT, rffi.INT],
rffi.INT,
compilation_info=eci,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
@@ -82,7 +86,7 @@
"sizehint must be greater than zero, got %d", sizehint)
epfd = epoll_create(sizehint)
if epfd < 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
return space.wrap(W_Epoll(space, epfd))
@@ -114,10 +118,10 @@
rffi.setintfield(ev.c_data, 'c_fd', fd)
result = epoll_ctl(self.epfd, ctl, fd, ev)
- if ignore_ebadf and get_errno() == errno.EBADF:
+ if ignore_ebadf and get_saved_errno() == errno.EBADF:
result = 0
if result < 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
def descr_get_closed(self, space):
return space.wrap(self.get_closed())
@@ -160,7 +164,7 @@
with lltype.scoped_alloc(rffi.CArray(epoll_event), maxevents) as evs:
nfds = epoll_wait(self.epfd, evs, maxevents, int(timeout))
if nfds < 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
elist_w = [None] * nfds
for i in xrange(nfds):
diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -1,5 +1,6 @@
from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.error import OperationError, exception_from_errno, oefmt
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import exception_from_saved_errno
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.interpreter.typedef import TypeDef, generic_new_descr, GetSetProperty
from rpython.rlib._rsocket_rffi import socketclose
@@ -86,7 +87,8 @@
"kqueue",
[],
rffi.INT,
- compilation_info=eci
+ compilation_info=eci,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
syscall_kevent = rffi.llexternal(
@@ -99,7 +101,8 @@
lltype.Ptr(timespec)
],
rffi.INT,
- compilation_info=eci
+ compilation_info=eci,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
@@ -110,7 +113,7 @@
def descr__new__(space, w_subtype):
kqfd = syscall_kqueue()
if kqfd < 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
return space.wrap(W_Kqueue(space, kqfd))
@unwrap_spec(fd=int)
@@ -198,7 +201,7 @@
max_events,
ptimeout)
if nfds < 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
else:
elist_w = [None] * nfds
for i in xrange(nfds):
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -5,7 +5,7 @@
import os
import errno
-from pypy.interpreter.error import OperationError, exception_from_errno
+from pypy.interpreter.error import OperationError, exception_from_saved_errno
from pypy.interpreter.executioncontext import (AsyncAction, AbstractActionFlag,
PeriodicAsyncAction)
from pypy.interpreter.gateway import unwrap_spec
@@ -258,7 +258,7 @@
def siginterrupt(space, signum, flag):
check_signum_in_range(space, signum)
if rffi.cast(lltype.Signed, c_siginterrupt(signum, flag)) < 0:
- errno = rposix.get_errno()
+ errno = rposix.get_saved_errno()
raise OperationError(space.w_RuntimeError, space.wrap(errno))
@@ -311,7 +311,7 @@
ret = c_setitimer(which, new, old)
if ret != 0:
- raise exception_from_errno(space, get_itimer_error(space))
+ raise exception_from_saved_errno(space, get_itimer_error(space))
return itimer_retval(space, old[0])
diff --git a/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py b/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py
--- a/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py
+++ b/rpython/jit/backend/llsupport/test/zrpy_releasegil_test.py
@@ -95,3 +95,24 @@
def test_close_stack(self):
self.run('close_stack')
assert 'call_release_gil' in udir.join('TestCompileFramework.log').read()
+
+ ## def define_get_set_errno(self):
+
+ ## c_strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed],
+ ## rffi.CCHARP, ...
+
+ ## def before(n, x):
+ ## return (n, None, None, None, None, None,
+ ## None, None, None, None, None, None)
+ ## #
+ ## def f(n, x, *args):
+ ## a = rffi.str2charp(str(n))
+ ## c_strchr(a, ord('0'))
+ ## lltype.free(a, flavor='raw')
+ ## n -= 1
+ ## return (n, x) + args
+ ## return before, f, None
+
+ ## def test_get_set_errno(self):
+ ## self.run('get_set_errno')
+ ## assert 'call_release_gil' in udir.join('TestCompileFramework.log').read()
diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py
--- a/rpython/jit/codewriter/call.py
+++ b/rpython/jit/codewriter/call.py
@@ -10,6 +10,7 @@
EffectInfo, CallInfoCollection)
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.rtyper.typesystem import getfunctionptr
+from rpython.rlib import rposix
from rpython.translator.backendopt.canraise import RaiseAnalyzer
from rpython.translator.backendopt.writeanalyze import ReadWriteAnalyzer
from rpython.translator.backendopt.graphanalyze import DependencyTracker
@@ -114,6 +115,10 @@
if self.jitdriver_sd_from_portal_runner_ptr(funcptr) is not None:
return 'recursive'
funcobj = funcptr._obj
+ assert (funcobj is not rposix._get_errno and
+ funcobj is not rposix._set_errno), (
+ "the JIT must never come close to _get_errno() or _set_errno();"
+ " it should all be done at a lower level")
if getattr(funcobj, 'graph', None) is None:
return 'residual'
targetgraph = funcobj.graph
@@ -206,7 +211,7 @@
# get the 'elidable' and 'loopinvariant' flags from the function object
elidable = False
loopinvariant = False
- call_release_gil_target = llmemory.NULL
+ call_release_gil_target = EffectInfo._NO_CALL_RELEASE_GIL_TARGET
if op.opname == "direct_call":
funcobj = op.args[0].value._obj
assert getattr(funcobj, 'calling_conv', 'c') == 'c', (
@@ -218,9 +223,9 @@
assert not NON_VOID_ARGS, ("arguments not supported for "
"loop-invariant function!")
if getattr(func, "_call_aroundstate_target_", None):
- call_release_gil_target = func._call_aroundstate_target_
- call_release_gil_target = llmemory.cast_ptr_to_adr(
- call_release_gil_target)
+ tgt_func, tgt_saveerr = func._call_aroundstate_target_
+ tgt_func = llmemory.cast_ptr_to_adr(tgt_func)
+ call_release_gil_target = (tgt_func, tgt_saveerr)
elif op.opname == 'indirect_call':
# check that we're not trying to call indirectly some
# function with the special flags
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -98,6 +98,8 @@
OS_NOT_IN_TRACE,
])
+ _NO_CALL_RELEASE_GIL_TARGET = (llmemory.NULL, 0)
+
def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
readonly_descrs_interiorfields,
write_descrs_fields, write_descrs_arrays,
@@ -105,7 +107,7 @@
extraeffect=EF_CAN_RAISE,
oopspecindex=OS_NONE,
can_invalidate=False,
- call_release_gil_target=llmemory.NULL,
+ call_release_gil_target=_NO_CALL_RELEASE_GIL_TARGET,
extradescrs=None):
key = (frozenset_or_none(readonly_descrs_fields),
frozenset_or_none(readonly_descrs_arrays),
@@ -116,7 +118,8 @@
extraeffect,
oopspecindex,
can_invalidate)
- if call_release_gil_target:
+ tgt_func, tgt_saveerr = call_release_gil_target
+ if tgt_func:
key += (object(),) # don't care about caching in this case
if key in cls._cache:
return cls._cache[key]
@@ -171,7 +174,8 @@
return self.extraeffect >= self.EF_RANDOM_EFFECTS
def is_call_release_gil(self):
- return bool(self.call_release_gil_target)
+ tgt_func, tgt_saveerr = self.call_release_gil_target
+ return bool(tgt_func)
def __repr__(self):
more = ''
@@ -194,7 +198,8 @@
extraeffect=EffectInfo.EF_CAN_RAISE,
oopspecindex=EffectInfo.OS_NONE,
can_invalidate=False,
- call_release_gil_target=llmemory.NULL,
+ call_release_gil_target=
+ EffectInfo._NO_CALL_RELEASE_GIL_TARGET,
extradescr=None):
from rpython.translator.backendopt.writeanalyze import top_set
if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py
--- a/rpython/rlib/clibffi.py
+++ b/rpython/rlib/clibffi.py
@@ -330,7 +330,8 @@
else:
c_ffi_call_return_type = lltype.Void
c_ffi_call = external('ffi_call', [FFI_CIFP, rffi.VOIDP, rffi.VOIDP,
- VOIDPP], c_ffi_call_return_type)
+ VOIDPP], c_ffi_call_return_type,
+ save_err=rffi.RFFI_ERR_ALL)
CALLBACK_TP = rffi.CCallback([FFI_CIFP, rffi.VOIDP, rffi.VOIDPP, rffi.VOIDP],
lltype.Void)
c_ffi_prep_closure = external('ffi_prep_closure', [FFI_CLOSUREP, FFI_CIFP,
diff --git a/rpython/rlib/rsignal.py b/rpython/rlib/rsignal.py
--- a/rpython/rlib/rsignal.py
+++ b/rpython/rlib/rsignal.py
@@ -89,10 +89,12 @@
elidable_function=True)
c_alarm = external('alarm', [rffi.INT], rffi.INT)
c_pause = external('pause', [], rffi.INT, releasegil=True)
-c_siginterrupt = external('siginterrupt', [rffi.INT, rffi.INT], rffi.INT)
+c_siginterrupt = external('siginterrupt', [rffi.INT, rffi.INT], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
if sys.platform != 'win32':
itimervalP = rffi.CArrayPtr(itimerval)
c_setitimer = external('setitimer',
- [rffi.INT, itimervalP, itimervalP], rffi.INT)
+ [rffi.INT, itimervalP, itimervalP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
c_getitimer = external('getitimer', [rffi.INT, itimervalP], 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
@@ -213,7 +213,7 @@
# CALL_RELEASE_GIL directly to 'funcptr'. This doesn't work if
# 'funcptr' might be a C macro, though.
if macro is None:
- call_external_function._call_aroundstate_target_ = funcptr
+ call_external_function._call_aroundstate_target_ = funcptr, save_err
#
call_external_function = func_with_new_name(call_external_function,
'ccall_' + name)
More information about the pypy-commit
mailing list