Revert changeset d927047b1d8eb87738676980a24930d053ba2150
Sorry, it was a mistake, the patch is still under review: issue #23646.
This commit is contained in:
parent
e010d8f031
commit
0c2fd89777
|
@ -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])
|
||||||
|
|
||||||
|
|
|
@ -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__":
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue