Revert changeset d927047b1d8eb87738676980a24930d053ba2150

Sorry, it was a mistake, the patch is still under review: issue #23646.
This commit is contained in:
Victor Stinner 2015-03-17 10:49:17 +01:00
parent e010d8f031
commit 0c2fd89777
4 changed files with 56 additions and 98 deletions

View File

@ -350,10 +350,6 @@ The module defines the following functions and data items:
requested by an arbitrary amount because of the scheduling of other activity requested by an arbitrary amount because of the scheduling of other activity
in the system. in the system.
.. versionchanged:: 3.5
The function now sleeps at least *secs* even if the sleep is interrupted
by a signal (see :pep:`475` for the rationale).
.. function:: strftime(format[, t]) .. function:: strftime(format[, t])

View File

@ -252,23 +252,8 @@ class SocketEINTRTest(EINTRBaseTest):
lambda path: os.close(os.open(path, os.O_WRONLY))) lambda path: os.close(os.open(path, os.O_WRONLY)))
@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()")
class TimeEINTRTest(EINTRBaseTest):
""" EINTR tests for the time module. """
def test_sleep(self):
t0 = time.monotonic()
time.sleep(2)
signal.alarm(0)
dt = time.monotonic() - t0
self.assertGreaterEqual(dt, 1.9)
def test_main(): def test_main():
support.run_unittest( support.run_unittest(OSEINTRTest, SocketEINTRTest)
OSEINTRTest,
SocketEINTRTest,
TimeEINTRTest)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -419,20 +419,17 @@ class WakeupSignalTests(unittest.TestCase):
TIMEOUT_HALF = 5 TIMEOUT_HALF = 5
signal.alarm(1) signal.alarm(1)
before_time = time.time()
# We attempt to get a signal during the sleep, # We attempt to get a signal during the sleep,
# before select is called # before select is called
try: time.sleep(TIMEOUT_FULL)
select.select([], [], [], TIMEOUT_FULL) mid_time = time.time()
except InterruptedError: dt = mid_time - before_time
pass if dt >= TIMEOUT_HALF:
else: raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
raise Exception("select() was not interrupted")
before_time = time.time()
select.select([read], [], [], TIMEOUT_FULL) select.select([read], [], [], TIMEOUT_FULL)
after_time = time.time() after_time = time.time()
dt = after_time - before_time dt = after_time - mid_time
if dt >= TIMEOUT_HALF: if dt >= TIMEOUT_HALF:
raise Exception("%s >= %s" % (dt, TIMEOUT_HALF)) raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
""", signal.SIGALRM) """, signal.SIGALRM)

View File

@ -1386,94 +1386,74 @@ floattime(_Py_clock_info_t *info)
static int static int
floatsleep(double secs) floatsleep(double secs)
{ {
_PyTime_timeval deadline, monotonic; /* XXX Should test for MS_WINDOWS first! */
#ifndef MS_WINDOWS #if defined(HAVE_SELECT) && !defined(__EMX__)
struct timeval timeout; struct timeval t;
double frac; double frac;
int err = 0; int err;
_PyTime_monotonic(&deadline); frac = fmod(secs, 1.0);
_PyTime_ADD_SECONDS(deadline, secs); secs = floor(secs);
t.tv_sec = (long)secs;
while (1) { t.tv_usec = (long)(frac*1000000.0);
frac = fmod(secs, 1.0); Py_BEGIN_ALLOW_THREADS
secs = floor(secs); err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
timeout.tv_sec = (long)secs; Py_END_ALLOW_THREADS
timeout.tv_usec = (long)(frac*1000000.0); if (err != 0) {
#ifdef EINTR
Py_BEGIN_ALLOW_THREADS if (errno == EINTR) {
err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); if (PyErr_CheckSignals())
Py_END_ALLOW_THREADS return -1;
}
if (!(err != 0 && errno == EINTR)) else
break; #endif
{
/* select() was interrupted by a signal */ PyErr_SetFromErrno(PyExc_OSError);
if (PyErr_CheckSignals())
return -1; return -1;
_PyTime_monotonic(&monotonic);
secs = _PyTime_INTERVAL(monotonic, deadline);
if (secs <= 0.0) {
err = 0;
errno = 0;
break;
} }
} }
#elif defined(__WATCOMC__) && !defined(__QNX__)
/* XXX Can't interrupt this sleep */
Py_BEGIN_ALLOW_THREADS
delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
Py_END_ALLOW_THREADS
#elif defined(MS_WINDOWS)
{
double millisecs = secs * 1000.0;
unsigned long ul_millis;
if (err != 0) {
PyErr_SetFromErrno(PyExc_OSError);
return -1;
}
#else
double millisecs;
unsigned long ul_millis;
DWORD rc;
HANDLE hInterruptEvent;
_PyTime_monotonic(&deadline);
_PyTime_ADD_SECONDS(deadline, secs);
do {
millisecs = secs * 1000.0;
if (millisecs > (double)ULONG_MAX) { if (millisecs > (double)ULONG_MAX) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"sleep length is too large"); "sleep length is too large");
return -1; return -1;
} }
Py_BEGIN_ALLOW_THREADS
/* Allow sleep(0) to maintain win32 semantics, and as decreed /* Allow sleep(0) to maintain win32 semantics, and as decreed
* by Guido, only the main thread can be interrupted. * by Guido, only the main thread can be interrupted.
*/ */
ul_millis = (unsigned long)millisecs; ul_millis = (unsigned long)millisecs;
if (ul_millis == 0 || !_PyOS_IsMainThread()) { if (ul_millis == 0 || !_PyOS_IsMainThread())
Py_BEGIN_ALLOW_THREADS Sleep(ul_millis);
Sleep(0);
Py_END_ALLOW_THREADS
break;
}
else { else {
hInterruptEvent = _PyOS_SigintEvent(); DWORD rc;
HANDLE hInterruptEvent = _PyOS_SigintEvent();
ResetEvent(hInterruptEvent); ResetEvent(hInterruptEvent);
Py_BEGIN_ALLOW_THREADS
rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE); rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
Py_END_ALLOW_THREADS if (rc == WAIT_OBJECT_0) {
Py_BLOCK_THREADS
if (rc != WAIT_OBJECT_0) errno = EINTR;
break; PyErr_SetFromErrno(PyExc_OSError);
/* WaitForSingleObjectEx() was interrupted by SIGINT */
if (PyErr_CheckSignals())
return -1; return -1;
}
_PyTime_monotonic(&monotonic);
secs = _PyTime_INTERVAL(monotonic, deadline);
if (secs <= 0.0)
break;
} }
} while (1); Py_END_ALLOW_THREADS
}
#else
/* XXX Can't interrupt this sleep */
Py_BEGIN_ALLOW_THREADS
sleep((int)secs);
Py_END_ALLOW_THREADS
#endif #endif
return 0; return 0;
} }