static int floatsleep(double secs) { /* XXX Should test for MS_WINDOWS first! */ #if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__) struct timeval t; double frac; frac = fmod(secs, 1.0); 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) { #ifdef EINTR if (errno != EINTR) { #else if (1) { #endif Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS #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 (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 || main_thread != PyThread_get_thread_ident()) Sleep(ul_millis); else { DWORD rc; ResetEvent(hInterruptEvent); rc = WaitForSingleObject(hInterruptEvent, ul_millis); if (rc == WAIT_OBJECT_0) { /* Yield to make sure real Python signal * handler called. */ Sleep(1); Py_BLOCK_THREADS errno = EINTR; PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS } #elif defined(PYOS_OS2) /* This Sleep *IS* Interruptable by Exceptions */ Py_BEGIN_ALLOW_THREADS if (DosSleep(secs * 1000) != NO_ERROR) { Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS #elif defined(__BEOS__) /* This sleep *CAN BE* interrupted. */ { if( secs <= 0.0 ) { return; } Py_BEGIN_ALLOW_THREADS /* BeOS snooze() is in microseconds... */ if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) { Py_BLOCK_THREADS PyErr_SetFromErrno( PyExc_IOError ); return -1; } Py_END_ALLOW_THREADS } #elif defined(RISCOS) if (secs <= 0.0) return 0; Py_BEGIN_ALLOW_THREADS /* This sleep *CAN BE* interrupted. */ if ( riscos_sleep(secs) ) return -1; Py_END_ALLOW_THREADS #elif defined(PLAN9) { double millisecs = secs * 1000.0; if (millisecs > (double)LONG_MAX) { PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } /* This sleep *CAN BE* interrupted. */ Py_BEGIN_ALLOW_THREADS if(sleep((long)millisecs) < 0){ Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -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; }
static int floatsleep(double secs) { /* XXX Should test for MS_WINDOWS first! */ #if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__) struct timeval t; double frac; #if defined (AMITCP) || defined(INET225) /* check for availability of an Amiga TCP stack for select() */ if(!checksocketlib()) { /* no bsdsocket.library-- use dos/Delay() */ PyErr_Clear(); Delay((long)(secs*50)); /* XXX Can't interrupt this sleep */ return 0; } #endif frac = fmod(secs, 1.0); 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) { #ifdef EINTR if (errno != EINTR) { #else if (1) { #endif Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS #elif defined(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; } #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 (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 || main_thread != PyThread_get_thread_ident()) Sleep(ul_millis); else { DWORD rc; ResetEvent(hInterruptEvent); rc = WaitForSingleObject(hInterruptEvent, ul_millis); if (rc == WAIT_OBJECT_0) { /* Yield to make sure real Python signal * handler called. */ Sleep(1); Py_BLOCK_THREADS errno = EINTR; PyErr_SetFromErrno(PyExc_IOError); return -1; } } Py_END_ALLOW_THREADS } #elif defined(PYOS_OS2) /* This Sleep *IS* Interruptable by Exceptions */ Py_BEGIN_ALLOW_THREADS if (DosSleep(secs * 1000) != NO_ERROR) { Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS #elif defined(__BEOS__) /* This sleep *CAN BE* interrupted. */ { if( secs <= 0.0 ) { return; } Py_BEGIN_ALLOW_THREADS /* BeOS snooze() is in microseconds... */ if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) { Py_BLOCK_THREADS PyErr_SetFromErrno( PyExc_IOError ); return -1; } Py_END_ALLOW_THREADS } #elif defined(RISCOS) if (secs <= 0.0) return 0; Py_BEGIN_ALLOW_THREADS /* This sleep *CAN BE* interrupted. */ if ( riscos_sleep(secs) ) return -1; Py_END_ALLOW_THREADS #elif defined(PLAN9) { double millisecs = secs * 1000.0; if (millisecs > (double)LONG_MAX) { PyErr_SetString(PyExc_OverflowError, "sleep length is too large"); return -1; } /* This sleep *CAN BE* interrupted. */ Py_BEGIN_ALLOW_THREADS if(sleep((long)millisecs) < 0){ Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_IOError); return -1; } Py_END_ALLOW_THREADS } #elif _AMIGA /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS Delay((long)(secs*50)); Py_END_ALLOW_THREADS #else /* !_AMIGA */ /* XXX Can't interrupt this sleep */ Py_BEGIN_ALLOW_THREADS sleep((int)secs); Py_END_ALLOW_THREADS #endif /* !_AMIGA */ /* XXX Can't interrupt this sleep */ return 0; }