Move the Py_{{BEGIN,END}_ALLOW,BLOCK}_THREADS macros in time_sleep()
to inside floatsleep(). This is necessary because floatsleep() does
the error handling and it must have grabbed the interpreter lock and
thread state before it can do so.
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 8b12508..e8de0ac 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -202,13 +202,9 @@
double secs;
if (!PyArg_Parse(args, "d", &secs))
return NULL;
- Py_BEGIN_ALLOW_THREADS
- if (floatsleep(secs) != 0) {
- Py_BLOCK_THREADS
- return NULL;
- }
- Py_END_ALLOW_THREADS
- Py_INCREF(Py_None);
+ if (floatsleep(secs) != 0)
+ return NULL;
+ Py_INCREF(Py_None);
return Py_None;
}
@@ -532,23 +528,29 @@
secs = floor(secs);
t.tv_sec = (long)secs;
t.tv_usec = (long)(frac*1000000.0);
+ Py_BEGIN_ALLOW_THREADS
if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
+ Py_BLOCK_THREADS
PyErr_SetFromErrno(PyExc_IOError);
return -1;
}
+ Py_END_ALLOW_THREADS
#else /* !HAVE_SELECT */
#ifdef macintosh
#define MacTicks (* (long *)0x16A)
long deadline;
deadline = MacTicks + (long)(secs * 60.0);
while (MacTicks < deadline) {
+ /* XXX Should call some yielding function here */
if (PyErr_CheckSignals())
return -1;
}
#else /* !macintosh */
#ifdef __WATCOMC__
/* XXX Can't interrupt this sleep */
+ Py_BEGIN_ALLOW_THREADS
delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
+ Py_END_ALLOW_THREADS
#else /* !__WATCOMC__ */
#ifdef MSDOS
struct timeb t1, t2;
@@ -568,7 +570,9 @@
}
for (;;) {
#ifdef QUICKWIN
+ Py_BEGIN_ALLOW_THREADS
_wyield();
+ Py_END_ALLOW_THREADS
#endif
if (PyErr_CheckSignals())
return -1;
@@ -580,10 +584,14 @@
#else /* !MSDOS */
#ifdef MS_WIN32
/* XXX Can't interrupt this sleep */
+ Py_BEGIN_ALLOW_THREADS
Sleep((int)(secs*1000));
+ Py_END_ALLOW_THREADS
#else /* !MS_WIN32 */
/* XXX Can't interrupt this sleep */
+ Py_BEGIN_ALLOW_THREADS
sleep((int)secs);
+ Py_END_ALLOW_THREADS
#endif /* !MS_WIN32 */
#endif /* !MSDOS */
#endif /* !__WATCOMC__ */