mirror of https://github.com/python/cpython
test
This commit is contained in:
parent
f7cc3fccad
commit
945c82eea3
|
@ -350,6 +350,10 @@ The module defines the following functions and data items:
|
|||
requested by an arbitrary amount because of the scheduling of other activity
|
||||
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])
|
||||
|
||||
|
|
|
@ -252,8 +252,23 @@ class SocketEINTRTest(EINTRBaseTest):
|
|||
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():
|
||||
support.run_unittest(OSEINTRTest, SocketEINTRTest)
|
||||
support.run_unittest(
|
||||
OSEINTRTest,
|
||||
SocketEINTRTest,
|
||||
TimeEINTRTest)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -419,17 +419,20 @@ class WakeupSignalTests(unittest.TestCase):
|
|||
TIMEOUT_HALF = 5
|
||||
|
||||
signal.alarm(1)
|
||||
before_time = time.time()
|
||||
|
||||
# We attempt to get a signal during the sleep,
|
||||
# before select is called
|
||||
time.sleep(TIMEOUT_FULL)
|
||||
mid_time = time.time()
|
||||
dt = mid_time - before_time
|
||||
if dt >= TIMEOUT_HALF:
|
||||
raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
|
||||
try:
|
||||
select.select([], [], [], TIMEOUT_FULL)
|
||||
except InterruptedError:
|
||||
pass
|
||||
else:
|
||||
raise Exception("select() was not interrupted")
|
||||
|
||||
before_time = time.time()
|
||||
select.select([read], [], [], TIMEOUT_FULL)
|
||||
after_time = time.time()
|
||||
dt = after_time - mid_time
|
||||
dt = after_time - before_time
|
||||
if dt >= TIMEOUT_HALF:
|
||||
raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
|
||||
""", signal.SIGALRM)
|
||||
|
|
|
@ -1386,74 +1386,94 @@ floattime(_Py_clock_info_t *info)
|
|||
static int
|
||||
floatsleep(double secs)
|
||||
{
|
||||
/* XXX Should test for MS_WINDOWS first! */
|
||||
#if defined(HAVE_SELECT) && !defined(__EMX__)
|
||||
struct timeval t;
|
||||
_PyTime_timeval deadline, monotonic;
|
||||
#ifndef MS_WINDOWS
|
||||
struct timeval timeout;
|
||||
double frac;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
frac = fmod(secs, 1.0);
|
||||
secs = floor(secs);
|
||||
t.tv_sec = (long)secs;
|
||||
t.tv_usec = (long)(frac*1000000.0);
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (err != 0) {
|
||||
#ifdef EINTR
|
||||
if (errno == EINTR) {
|
||||
if (PyErr_CheckSignals())
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
_PyTime_monotonic(&deadline);
|
||||
_PyTime_ADD_SECONDS(deadline, secs);
|
||||
|
||||
while (1) {
|
||||
frac = fmod(secs, 1.0);
|
||||
secs = floor(secs);
|
||||
timeout.tv_sec = (long)secs;
|
||||
timeout.tv_usec = (long)(frac*1000000.0);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (!(err != 0 && errno == EINTR))
|
||||
break;
|
||||
|
||||
/* select() was interrupted by a signal */
|
||||
if (PyErr_CheckSignals())
|
||||
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) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"sleep length is too large");
|
||||
return -1;
|
||||
}
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
|
||||
/* Allow sleep(0) to maintain win32 semantics, and as decreed
|
||||
* by Guido, only the main thread can be interrupted.
|
||||
*/
|
||||
ul_millis = (unsigned long)millisecs;
|
||||
if (ul_millis == 0 || !_PyOS_IsMainThread())
|
||||
Sleep(ul_millis);
|
||||
else {
|
||||
DWORD rc;
|
||||
HANDLE hInterruptEvent = _PyOS_SigintEvent();
|
||||
ResetEvent(hInterruptEvent);
|
||||
rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
|
||||
if (rc == WAIT_OBJECT_0) {
|
||||
Py_BLOCK_THREADS
|
||||
errno = EINTR;
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
return -1;
|
||||
}
|
||||
if (ul_millis == 0 || !_PyOS_IsMainThread()) {
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
Sleep(0);
|
||||
Py_END_ALLOW_THREADS
|
||||
break;
|
||||
}
|
||||
Py_END_ALLOW_THREADS
|
||||
}
|
||||
#else
|
||||
/* XXX Can't interrupt this sleep */
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
sleep((int)secs);
|
||||
Py_END_ALLOW_THREADS
|
||||
#endif
|
||||
else {
|
||||
hInterruptEvent = _PyOS_SigintEvent();
|
||||
ResetEvent(hInterruptEvent);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (rc != WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
/* WaitForSingleObjectEx() was interrupted by SIGINT */
|
||||
|
||||
if (PyErr_CheckSignals())
|
||||
return -1;
|
||||
|
||||
_PyTime_monotonic(&monotonic);
|
||||
secs = _PyTime_INTERVAL(monotonic, deadline);
|
||||
if (secs <= 0.0)
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue