diff options
author | Livius <egyszeregy@freemail.hu> | 2021-09-13 12:37:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-13 12:37:38 (GMT) |
commit | 85a4748118c3793be7047ecbcbfc79dd07cb2a75 (patch) | |
tree | 8faca8b6e772af6312db9daa26f4d89b1e29a3bd /Modules/timemodule.c | |
parent | 3e19409d6443c66a6a7d62f58b2bb4e8330e56c4 (diff) | |
download | cpython-85a4748118c3793be7047ecbcbfc79dd07cb2a75.zip cpython-85a4748118c3793be7047ecbcbfc79dd07cb2a75.tar.gz cpython-85a4748118c3793be7047ecbcbfc79dd07cb2a75.tar.bz2 |
bpo-21302: Add clock_nanosleep() implementation for time.sleep() (GH-28111)
In Unix operating systems, time.sleep() now uses the clock_nanosleep() function,
if available, which allows to sleep for an interval specified with nanosecond precision.
Co-authored-by: Victor Stinner <vstinner@python.org>
Diffstat (limited to 'Modules/timemodule.c')
-rw-r--r-- | Modules/timemodule.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 4caacc3..cf58a18 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -2053,8 +2053,13 @@ pysleep(_PyTime_t secs) { _PyTime_t deadline, monotonic; #ifndef MS_WINDOWS +#ifdef HAVE_CLOCK_NANOSLEEP + struct timespec timeout_abs; +#else struct timeval timeout; +#endif int err = 0; + int ret = 0; #else _PyTime_t millisecs; unsigned long ul_millis; @@ -2066,20 +2071,38 @@ pysleep(_PyTime_t secs) return -1; } deadline = monotonic + secs; +#if defined(HAVE_CLOCK_NANOSLEEP) && !defined(MS_WINDOWS) + if (_PyTime_AsTimespec(deadline, &timeout_abs) < 0) { + return -1; + } +#endif do { #ifndef MS_WINDOWS - if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) +#ifndef HAVE_CLOCK_NANOSLEEP + if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) { return -1; + } +#endif +#ifdef HAVE_CLOCK_NANOSLEEP Py_BEGIN_ALLOW_THREADS - err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); + ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &timeout_abs, NULL); Py_END_ALLOW_THREADS + err = ret; +#else + Py_BEGIN_ALLOW_THREADS + ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout); + Py_END_ALLOW_THREADS + err = errno; +#endif - if (err == 0) + if (ret == 0) { break; + } - if (errno != EINTR) { + if (err != EINTR) { + errno = err; PyErr_SetFromErrno(PyExc_OSError); return -1; } @@ -2114,9 +2137,11 @@ pysleep(_PyTime_t secs) #endif /* sleep was interrupted by SIGINT */ - if (PyErr_CheckSignals()) + if (PyErr_CheckSignals()) { return -1; + } +#ifndef HAVE_CLOCK_NANOSLEEP if (get_monotonic(&monotonic) < 0) { return -1; } @@ -2125,6 +2150,7 @@ pysleep(_PyTime_t secs) break; } /* retry with the recomputed delay */ +#endif } while (1); return 0; |