summaryrefslogtreecommitdiffstats
path: root/Modules/timemodule.c
diff options
context:
space:
mode:
authorMark Hammond <mhammond@skippinet.com.au>2002-07-16 01:29:19 (GMT)
committerMark Hammond <mhammond@skippinet.com.au>2002-07-16 01:29:19 (GMT)
commit975e3921aeee512fabf3d4cdf068d7723f163b2b (patch)
treeb116c3bbd3dd6503ed4db16728d1bb55bbede16f /Modules/timemodule.c
parent0756a5e97affde3bd6f8a87b1e5594393fafc114 (diff)
downloadcpython-975e3921aeee512fabf3d4cdf068d7723f163b2b.zip
cpython-975e3921aeee512fabf3d4cdf068d7723f163b2b.tar.gz
cpython-975e3921aeee512fabf3d4cdf068d7723f163b2b.tar.bz2
Fix bug 581232 - [Windows] Can not interrupt time.sleep()
time.sleep() will now be interrupted on the main thread when Ctrl+C is pressed. Other threads are never interrupted.
Diffstat (limited to 'Modules/timemodule.c')
-rw-r--r--Modules/timemodule.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 8f2c4f8..dbb4456 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -28,7 +28,24 @@ extern int ftime(struct timeb *);
#include <i86.h>
#else
#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include "pythread.h"
+
+/* helper to allow us to interrupt sleep() on Windows*/
+static HANDLE hInterruptEvent = NULL;
+static BOOL WINAPI PyCtrlHandler(DWORD dwCtrlType)
+{
+ SetEvent(hInterruptEvent);
+ /* allow other default handlers to be called.
+ Default Python handler will setup the
+ KeyboardInterrupt exception.
+ */
+ return FALSE;
+}
+static long main_thread;
+
+
#if defined(__BORLANDC__)
/* These overrides not needed for Win32 */
#define timezone _timezone
@@ -680,7 +697,15 @@ inittime(void)
Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
#endif /* __CYGWIN__ */
#endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
-
+#ifdef MS_WINDOWS
+ /* Helper to allow interrupts for Windows.
+ If Ctrl+C event delivered while not sleeping
+ it will be ignored.
+ */
+ main_thread = PyThread_get_thread_ident();
+ hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
+#endif /* MS_WINDOWS */
PyStructSequence_InitType(&StructTimeType, &struct_time_type_desc);
Py_INCREF(&StructTimeType);
PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
@@ -775,9 +800,27 @@ floatsleep(double secs)
PyErr_SetString(PyExc_OverflowError, "sleep length is too large");
return -1;
}
- /* XXX Can't interrupt this sleep */
Py_BEGIN_ALLOW_THREADS
- Sleep((unsigned long)millisecs);
+ /* allow sleep(0) to maintain win32 semantics, and as decreed by
+ Guido, only the main thread can be interrupted. */
+ if ((unsigned long)millisecs==0 || main_thread != PyThread_get_thread_ident())
+ Sleep((unsigned long)millisecs);
+ else {
+ DWORD rc;
+ ResetEvent(hInterruptEvent);
+ rc = WaitForSingleObject(hInterruptEvent, (unsigned long)millisecs);
+ if (rc==WAIT_OBJECT_0) {
+ /* yield to make sure real Python signal handler called */
+ Sleep(1);
+ Py_BLOCK_THREADS
+ /* PyErr_SetFromErrno() does the "right thing" wrt signals
+ if errno=EINTR
+ */
+ errno = EINTR;
+ PyErr_SetFromErrno(PyExc_IOError);
+ return -1;
+ }
+ }
Py_END_ALLOW_THREADS
}
#elif defined(PYOS_OS2)