summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorLivius <egyszeregy@freemail.hu>2021-09-13 12:37:38 (GMT)
committerGitHub <noreply@github.com>2021-09-13 12:37:38 (GMT)
commit85a4748118c3793be7047ecbcbfc79dd07cb2a75 (patch)
tree8faca8b6e772af6312db9daa26f4d89b1e29a3bd /Modules
parent3e19409d6443c66a6a7d62f58b2bb4e8330e56c4 (diff)
downloadcpython-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')
-rw-r--r--Modules/timemodule.c36
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;