summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/time.rst4
-rw-r--r--Lib/test/eintrdata/eintr_tester.py17
-rw-r--r--Lib/test/test_signal.py17
-rw-r--r--Modules/timemodule.c118
4 files changed, 57 insertions, 99 deletions
diff --git a/Doc/library/time.rst b/Doc/library/time.rst
index f5e08c5..6bfd521 100644
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -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
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])
diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py
index 8547576..40dca84 100644
--- a/Lib/test/eintrdata/eintr_tester.py
+++ b/Lib/test/eintrdata/eintr_tester.py
@@ -252,23 +252,8 @@ 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,
- TimeEINTRTest)
+ support.run_unittest(OSEINTRTest, SocketEINTRTest)
if __name__ == "__main__":
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 6ecff9e..774fc80 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -419,20 +419,17 @@ 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
- try:
- select.select([], [], [], TIMEOUT_FULL)
- except InterruptedError:
- pass
- else:
- raise Exception("select() was not interrupted")
-
- before_time = time.time()
+ time.sleep(TIMEOUT_FULL)
+ mid_time = time.time()
+ dt = mid_time - before_time
+ if dt >= TIMEOUT_HALF:
+ raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
select.select([read], [], [], TIMEOUT_FULL)
after_time = time.time()
- dt = after_time - before_time
+ dt = after_time - mid_time
if dt >= TIMEOUT_HALF:
raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
""", signal.SIGALRM)
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 0eb78e9..7f5f314 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -1386,94 +1386,74 @@ floattime(_Py_clock_info_t *info)
static int
floatsleep(double secs)
{
- _PyTime_timeval deadline, monotonic;
-#ifndef MS_WINDOWS
- struct timeval timeout;
+/* XXX Should test for MS_WINDOWS first! */
+#if defined(HAVE_SELECT) && !defined(__EMX__)
+ struct timeval t;
double frac;
- int err = 0;
-
- _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())
+ int err;
+
+ 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);
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()) {
- Py_BEGIN_ALLOW_THREADS
- Sleep(0);
- Py_END_ALLOW_THREADS
- break;
- }
+ if (ul_millis == 0 || !_PyOS_IsMainThread())
+ Sleep(ul_millis);
else {
- hInterruptEvent = _PyOS_SigintEvent();
+ DWORD rc;
+ HANDLE 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())
+ if (rc == WAIT_OBJECT_0) {
+ Py_BLOCK_THREADS
+ errno = EINTR;
+ PyErr_SetFromErrno(PyExc_OSError);
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
+
return 0;
}