aboutsummaryrefslogtreecommitdiff
path: root/src/platform/posix
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/posix')
-rw-r--r--src/platform/posix/CMakeLists.txt1
-rw-r--r--src/platform/posix/posix_clock.c67
2 files changed, 51 insertions, 17 deletions
diff --git a/src/platform/posix/CMakeLists.txt b/src/platform/posix/CMakeLists.txt
index a00ffa50..857c340a 100644
--- a/src/platform/posix/CMakeLists.txt
+++ b/src/platform/posix/CMakeLists.txt
@@ -63,6 +63,7 @@ if (NNG_PLATFORM_POSIX)
nng_check_sym(atomic_flag_test_and_set stdatomic.h NNG_HAVE_STDATOMIC)
nng_check_sym(socketpair sys/socket.h NNG_HAVE_SOCKETPAIR)
nng_check_sym(AF_INET6 netinet/in.h NNG_HAVE_INET6)
+ nng_check_sym(timespec_get time.h NNG_HAVE_TIMESPEC_GET)
nng_sources(
posix_impl.h
diff --git a/src/platform/posix/posix_clock.c b/src/platform/posix/posix_clock.c
index 0db447e9..fa64c2d6 100644
--- a/src/platform/posix/posix_clock.c
+++ b/src/platform/posix/posix_clock.c
@@ -10,13 +10,44 @@
// POSIX clock stuff.
#include "core/nng_impl.h"
+#include "platform/posix/posix_impl.h"
#ifdef NNG_PLATFORM_POSIX
#include <errno.h>
#include <string.h>
+#include <sys/time.h>
#include <time.h>
+int
+nni_time_get(uint64_t *sec, uint32_t *nsec)
+{
+ int rv;
+#if defined(NNG_HAVE_TIMESPEC_GET)
+ struct timespec ts;
+ if ((rv = timespec_get(&ts, TIME_UTC)) == TIME_UTC) {
+ *sec = ts.tv_sec;
+ *nsec = ts.tv_nsec;
+ return (0);
+ }
+#elif defined(NNG_HAVE_CLOCK_GETTIME)
+ struct timespec ts;
+ if ((rv = clock_gettime(CLOCK_REALTIME, &ts)) == 0) {
+ *sec = ts.tv_sec;
+ *nsec = ts.tv_nsec;
+ return (0);
+ }
+#else
+ struct timeval tv;
+ if ((rv = gettimeofday(&tv, NULL)) == 0) {
+ *sec = tv.tv_sec;
+ *nsec = tv.tv_usec * 1000;
+ return (0);
+ }
+#endif
+ return (nni_plat_errno(errno));
+}
+
#if defined(NNG_HAVE_CLOCK_GETTIME) && !defined(NNG_USE_GETTIMEOFDAY)
// Use POSIX realtime stuff
@@ -45,7 +76,8 @@ nni_msleep(nni_duration ms)
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000;
- // Do this in a loop, so that interrupts don't actually wake us.
+ // Do this in a loop, so that interrupts don't actually wake
+ // us.
while (ts.tv_sec || ts.tv_nsec) {
if (nanosleep(&ts, &ts) == 0) {
break;
@@ -55,14 +87,15 @@ nni_msleep(nni_duration ms)
#else // NNG_USE_GETTIMEOFDAY
-// If you're here, its because you don't have a modern clock_gettime with
-// monotonic clocks, or the necessary pthread_condattr_settclock(). In
-// this case, you should be advised that *bad* things can happen if your
-// system clock changes time while programs using this library are running.
-// (Basically, timeouts can take longer or shorter, leading to either hangs
-// or apparent spurious errors. Eventually it should all sort itself out,
-// but if you change the clock by a large amount you might wonder what the
-// heck is happening until it does.)
+// If you're here, its because you don't have a modern clock_gettime
+// with monotonic clocks, or the necessary
+// pthread_condattr_settclock(). In this case, you should be advised
+// that *bad* things can happen if your system clock changes time while
+// programs using this library are running. (Basically, timeouts can
+// take longer or shorter, leading to either hangs or apparent spurious
+// errors. Eventually it should all sort itself out, but if you change
+// the clock by a large amount you might wonder what the heck is
+// happening until it does.)
#include <poll.h>
#include <pthread.h>
@@ -90,18 +123,18 @@ nni_msleep(nni_duration ms)
{
// So probably there is no nanosleep. We could in theory use
// pthread condition variables, but that means doing memory
- // allocation, or forcing the use of pthreads where the platform
- // might be preferring the use of another threading package.
- // Additionally, use of pthreads means that we cannot use
- // relative times in a clock_settime safe manner.
- // So we can use poll() instead.
+ // allocation, or forcing the use of pthreads where the
+ // platform might be preferring the use of another threading
+ // package. Additionally, use of pthreads means that we cannot
+ // use relative times in a clock_settime safe manner. So we can
+ // use poll() instead.
struct pollfd pfd;
nni_time now;
nni_time expire;
- // Possibly we could pass NULL instead of pfd, but passing a valid
- // pointer ensures that if the system dereferences the pointer it
- // won't come back with EFAULT.
+ // Possibly we could pass NULL instead of pfd, but passing a
+ // valid pointer ensures that if the system dereferences the
+ // pointer it won't come back with EFAULT.
pfd.fd = -1;
pfd.events = 0;