Author: Amaury Forgeot d'Arc <amaur...@gmail.com> Branch: py3.5 Changeset: r90904:8a164b222d5a Date: 2017-04-01 20:37 +0200 http://bitbucket.org/pypy/pypy/changeset/8a164b222d5a/
Log: (blind) attempt to support EINTR in win32's sleep(). Based on CPython b1abd06465fc diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py --- a/pypy/module/time/interp_time.py +++ b/pypy/module/time/interp_time.py @@ -447,17 +447,31 @@ errno = rposix.get_saved_errno() return _strerror(errno) -if sys.platform != 'win32': - from errno import EINTR - from rpython.rlib.rtime import c_select +from errno import EINTR +from rpython.rlib.rtime import c_select - @unwrap_spec(secs=float) - def sleep(space, secs): - if secs < 0: - raise oefmt(space.w_ValueError, - "sleep length must be non-negative") - end_time = timeutils.monotonic(space) + secs - while True: +@unwrap_spec(secs=float) +def sleep(space, secs): + if secs < 0: + raise oefmt(space.w_ValueError, + "sleep length must be non-negative") + end_time = timeutils.monotonic(space) + secs + while True: + if _WIN: + # as decreed by Guido, only the main thread can be + # interrupted. + main_thread = space.fromcache(State).main_thread + interruptible = (main_thread == thread.get_ident()) + millisecs = int(secs * 1000) + if millisecs == 0.0 or not interruptible: + rtime.sleep(secs) + break + interrupt_event = space.fromcache(State).get_interrupt_event() + rwin32.ResetEvent(interrupt_event) + rc = rwin32.WaitForSingleObject(interrupt_event, millisecs) + if rc != rwin32.WAIT_OBJECT_0: + break + else: void = lltype.nullptr(rffi.VOIDP.TO) with lltype.scoped_alloc(TIMEVAL) as t: frac = math.fmod(secs, 1.0) @@ -469,43 +483,10 @@ break # normal path if rposix.get_saved_errno() != EINTR: raise exception_from_saved_errno(space, space.w_OSError) - space.getexecutioncontext().checksignals() - secs = end_time - timeutils.monotonic(space) # retry - if secs <= 0.0: - break - -else: - from rpython.rlib import rwin32 - from errno import EINTR - def _simple_sleep(space, secs, interruptible): - if secs == 0.0 or not interruptible: - rtime.sleep(secs) - else: - millisecs = int(secs * 1000) - interrupt_event = space.fromcache(State).get_interrupt_event() - rwin32.ResetEvent(interrupt_event) - rc = rwin32.WaitForSingleObject(interrupt_event, millisecs) - if rc == rwin32.WAIT_OBJECT_0: - # Yield to make sure real Python signal handler - # called. - rtime.sleep(0.001) - raise wrap_oserror(space, - OSError(EINTR, "sleep() interrupted")) - @unwrap_spec(secs=float) - def sleep(space, secs): - XXX # review for EINTR / PEP475 - if secs < 0: - raise oefmt(space.w_ValueError, - "sleep length must be non-negative") - # as decreed by Guido, only the main thread can be - # interrupted. - main_thread = space.fromcache(State).main_thread - interruptible = (main_thread == thread.get_ident()) - MAX = sys.maxint / 1000.0 # > 24 days - while secs > MAX: - _simple_sleep(space, MAX, interruptible) - secs -= MAX - _simple_sleep(space, secs, interruptible) + space.getexecutioncontext().checksignals() + secs = end_time - timeutils.monotonic(space) # retry + if secs <= 0.0: + break def _get_module_object(space, obj_name): w_module = space.getbuiltinmodule('time') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit