summaryrefslogtreecommitdiffstats
path: root/src/H5system.c
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2019-09-10 20:27:38 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2019-09-10 20:27:38 (GMT)
commit9e2d4344de72a5e69e28629a11d918675877dfe4 (patch)
tree844461958cd2620cad2b32d140e548eef0d33ae9 /src/H5system.c
parent508cfab552d844c1ea313af99b5e815e87053c7c (diff)
downloadhdf5-9e2d4344de72a5e69e28629a11d918675877dfe4.zip
hdf5-9e2d4344de72a5e69e28629a11d918675877dfe4.tar.gz
hdf5-9e2d4344de72a5e69e28629a11d918675877dfe4.tar.bz2
Merge the latest h5_retry_t code from my `sleepy` branch.
Diffstat (limited to 'src/H5system.c')
-rw-r--r--src/H5system.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/H5system.c b/src/H5system.c
index 2d29650..55cac8d 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -1192,15 +1192,32 @@ done:
void
H5_nanosleep(uint64_t nanosec)
{
+ const uint64_t nanosec_per_sec = 1000 * 1000 * 1000;
struct timespec sleeptime; /* Struct to hold time to sleep */
FUNC_ENTER_NOAPI_NOINIT_NOERR
- /* Set up time to sleep */
- sleeptime.tv_sec = 0;
- sleeptime.tv_nsec = (long)nanosec;
+ /* Set up time to sleep
+ *
+ * Assuming ILP32 or LP64 or wider architecture, (long)operand
+ * satisfies 0 <= operand < nanosec_per_sec < LONG_MAX.
+ *
+ * It's harder to be sure that we don't overflow time_t.
+ */
+ sleeptime.tv_sec = (time_t)(nanosec / nanosec_per_sec);
+ sleeptime.tv_nsec = (long)(nanosec % nanosec_per_sec);
- HDnanosleep(&sleeptime, NULL);
+ /* Sleep for up to `sleeptime` and, in the event of an interruption,
+ * save the unslept time back to `sleeptime`.
+ */
+ while (HDnanosleep(&sleeptime, &sleeptime) == -1) {
+ /* If we were just interrupted, sleep for the remaining time.
+ * Otherwise, the error was essentially impossible, so just stop
+ * sleeping.
+ */
+ if (errno != EINTR)
+ break;
+ }
FUNC_LEAVE_NOAPI_VOID
} /* end H5_nanosleep() */