Skip to content

Commit

Permalink
Fix bug 581232 - [Windows] Can not interrupt time.sleep()
Browse files Browse the repository at this point in the history
time.sleep() will now be interrupted on the main thread when Ctrl+C is pressed.  Other threads are never interrupted.
  • Loading branch information
mhammond committed Jul 16, 2002
1 parent 0756a5e commit 975e392
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions Modules/timemodule.c
Expand Up @@ -28,7 +28,24 @@ extern int ftime(struct timeb *);
#include <i86.h> #include <i86.h>
#else #else
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h> #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__) #if defined(__BORLANDC__)
/* These overrides not needed for Win32 */ /* These overrides not needed for Win32 */
#define timezone _timezone #define timezone _timezone
Expand Down Expand Up @@ -680,7 +697,15 @@ inittime(void)
Py_BuildValue("(zz)", _tzname[0], _tzname[1])); Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
#endif /* __CYGWIN__ */ #endif /* __CYGWIN__ */
#endif /* !HAVE_TZNAME || __GLIBC__ || __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); PyStructSequence_InitType(&StructTimeType, &struct_time_type_desc);
Py_INCREF(&StructTimeType); Py_INCREF(&StructTimeType);
PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType); PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
Expand Down Expand Up @@ -775,9 +800,27 @@ floatsleep(double secs)
PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); PyErr_SetString(PyExc_OverflowError, "sleep length is too large");
return -1; return -1;
} }
/* XXX Can't interrupt this sleep */
Py_BEGIN_ALLOW_THREADS 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 Py_END_ALLOW_THREADS
} }
#elif defined(PYOS_OS2) #elif defined(PYOS_OS2)
Expand Down

0 comments on commit 975e392

Please sign in to comment.