|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Ben Noordhuis <info@bnoordhuis.nl> |
| 3 | +Date: Wed, 1 Jul 2020 10:32:57 +0200 |
| 4 | +Subject: darwin: work around clock jumping back in time |
| 5 | + |
| 6 | +It was reported that mach_absolute_time() can jump backward in time when |
| 7 | +the machine is suspended. Use mach_continuous_time() when available to |
| 8 | +work around that (macOS 10.12 and up.) |
| 9 | + |
| 10 | +Fixes: https://github.com/libuv/libuv/issues/2891 |
| 11 | +PR-URL: https://github.com/libuv/libuv/pull/2894 |
| 12 | +Reviewed-By: Phil Willoughby <philwill@fb.com> |
| 13 | +Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> |
| 14 | + |
| 15 | +diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c |
| 16 | +index 5cf03aea0b405402b88494f3840bcfe606551b53..030ed1adb23966f89877135dd0bd20629248f007 100644 |
| 17 | +--- a/deps/uv/src/unix/darwin.c |
| 18 | ++++ b/deps/uv/src/unix/darwin.c |
| 19 | +@@ -25,6 +25,7 @@ |
| 20 | + #include <stdint.h> |
| 21 | + #include <errno.h> |
| 22 | + |
| 23 | ++#include <dlfcn.h> |
| 24 | + #include <mach/mach.h> |
| 25 | + #include <mach/mach_time.h> |
| 26 | + #include <mach-o/dyld.h> /* _NSGetExecutablePath */ |
| 27 | +@@ -32,6 +33,10 @@ |
| 28 | + #include <sys/sysctl.h> |
| 29 | + #include <unistd.h> /* sysconf */ |
| 30 | + |
| 31 | ++static uv_once_t once = UV_ONCE_INIT; |
| 32 | ++static uint64_t (*time_func)(void); |
| 33 | ++static mach_timebase_info_data_t timebase; |
| 34 | ++ |
| 35 | + |
| 36 | + int uv__platform_loop_init(uv_loop_t* loop) { |
| 37 | + loop->cf_state = NULL; |
| 38 | +@@ -48,15 +53,19 @@ void uv__platform_loop_delete(uv_loop_t* loop) { |
| 39 | + } |
| 40 | + |
| 41 | + |
| 42 | +-uint64_t uv__hrtime(uv_clocktype_t type) { |
| 43 | +- static mach_timebase_info_data_t info; |
| 44 | +- |
| 45 | +- if ((ACCESS_ONCE(uint32_t, info.numer) == 0 || |
| 46 | +- ACCESS_ONCE(uint32_t, info.denom) == 0) && |
| 47 | +- mach_timebase_info(&info) != KERN_SUCCESS) |
| 48 | ++static void uv__hrtime_init_once(void) { |
| 49 | ++ if (KERN_SUCCESS != mach_timebase_info(&timebase)) |
| 50 | + abort(); |
| 51 | + |
| 52 | +- return mach_absolute_time() * info.numer / info.denom; |
| 53 | ++ time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time"); |
| 54 | ++ if (time_func == NULL) |
| 55 | ++ time_func = mach_absolute_time; |
| 56 | ++} |
| 57 | ++ |
| 58 | ++ |
| 59 | ++uint64_t uv__hrtime(uv_clocktype_t type) { |
| 60 | ++ uv_once(&once, uv__hrtime_init_once); |
| 61 | ++ return time_func() * timebase.numer / timebase.denom; |
| 62 | + } |
| 63 | + |
| 64 | + |
0 commit comments