Skip to content

Commit 3754e9e

Browse files
committed
Ensure that time.sleep(0) does not accumulate delays.
On non-Windows platforms, this reverts the usage of `clock_nanosleep` and `nanosleep` introduced by 85a4748 and 7834ff2 respectively, falling back to a `select(2)` alternative instead.
1 parent 76f1785 commit 3754e9e

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

Modules/timemodule.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ module time
7272

7373
/* Forward declarations */
7474
static int pysleep(PyTime_t timeout);
75+
#ifndef MS_WINDOWS
76+
static int pysleep_zero_posix(void);
77+
#endif
7578

7679

7780
typedef struct {
@@ -2213,6 +2216,11 @@ static int
22132216
pysleep(PyTime_t timeout)
22142217
{
22152218
assert(timeout >= 0);
2219+
#ifndef MS_WINDOWS
2220+
if (timeout == 0) {
2221+
return pysleep_zero_posix();
2222+
}
2223+
#endif
22162224

22172225
#ifndef MS_WINDOWS
22182226
#ifdef HAVE_CLOCK_NANOSLEEP
@@ -2390,3 +2398,44 @@ pysleep(PyTime_t timeout)
23902398
return -1;
23912399
#endif
23922400
}
2401+
2402+
2403+
#ifndef MS_WINDWOS
2404+
// time.sleep(0) optimized implementation.
2405+
// On error, raise an exception and return -1.
2406+
// On success, return 0.
2407+
static int
2408+
pysleep_zero_posix(void)
2409+
{
2410+
static struct timeval zero = {0, 0};
2411+
2412+
PyTime_t deadline, monotonic;
2413+
if (PyTime_Monotonic(&monotonic) < 0) {
2414+
return -1;
2415+
}
2416+
deadline = monotonic;
2417+
do {
2418+
int ret, err;
2419+
Py_BEGIN_ALLOW_THREADS
2420+
ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &zero);
2421+
err = errno;
2422+
Py_END_ALLOW_THREADS
2423+
if (ret == 0) {
2424+
break;
2425+
}
2426+
if (err != EINTR) {
2427+
errno = err;
2428+
PyErr_SetFromErrno(PyExc_OSError);
2429+
return -1;
2430+
}
2431+
/* sleep was interrupted by SIGINT */
2432+
if (PyErr_CheckSignals()) {
2433+
return -1;
2434+
}
2435+
if (PyTime_Monotonic(&monotonic) < 0) {
2436+
return -1;
2437+
}
2438+
} while (monotonic == deadline);
2439+
return 0;
2440+
}
2441+
#endif

0 commit comments

Comments
 (0)