• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_TIME_TIME_OVERRIDE_H_
6 #define BASE_TIME_TIME_OVERRIDE_H_
7 
8 #include <atomic>
9 #include <optional>
10 
11 #include "base/base_export.h"
12 #include "base/time/time.h"
13 #include "build/build_config.h"
14 
15 namespace base {
16 
17 using TimeNowFunction = decltype(&Time::Now);
18 using TimeTicksNowFunction = decltype(&TimeTicks::Now);
19 using TimeTicksLowResolutionNowFunction =
20     decltype(&TimeTicks::LowResolutionNow);
21 using LiveTicksNowFunction = decltype(&LiveTicks::Now);
22 using ThreadTicksNowFunction = decltype(&ThreadTicks::Now);
23 
24 // Time overrides should be used with extreme caution. Discuss with //base/time
25 // OWNERS before adding a new one.
26 namespace subtle {
27 
28 // Override the return value of Time::Now and Time::NowFromSystemTime /
29 // TimeTicks::Now / LiveTicks::Now / ThreadTicks::Now to emulate time, e.g. for
30 // tests or to modify progression of time. It is recommended that the override
31 // be set while single-threaded and before the first call to Now() to avoid
32 // threading issues and inconsistencies in returned values. Overriding time
33 // while other threads are running is very subtle and should be reserved for
34 // developer only use cases (e.g. virtual time in devtools) where any flakiness
35 // caused by a racy time update isn't surprising. Instantiating a
36 // ScopedTimeClockOverrides while other threads are running might break their
37 // expectation that TimeTicks and ThreadTicks increase monotonically. Nested
38 // overrides are not allowed.
39 class BASE_EXPORT ScopedTimeClockOverrides {
40  public:
41   // Pass |nullptr| for any override if it shouldn't be overriden.
42   ScopedTimeClockOverrides(TimeNowFunction time_override,
43                            TimeTicksNowFunction time_ticks_override,
44                            ThreadTicksNowFunction thread_ticks_override,
45                            LiveTicksNowFunction live_ticks_override = nullptr,
46                            TimeTicksLowResolutionNowFunction
47                                time_ticks_low_resolution_override = nullptr);
48 
49   ScopedTimeClockOverrides(const ScopedTimeClockOverrides&) = delete;
50   ScopedTimeClockOverrides& operator=(const ScopedTimeClockOverrides&) = delete;
51 
52   // Restores the platform default Now() functions.
53   ~ScopedTimeClockOverrides();
54 
overrides_active()55   static bool overrides_active() { return overrides_active_; }
56 
57  private:
58   static bool overrides_active_;
59 };
60 
61 // These methods return the platform default Time::Now / TimeTicks::Now /
62 // ThreadTicks::Now values even while an override is in place. These methods
63 // should only be used in places where emulated time should be disregarded. For
64 // example, they can be used to implement test timeouts for tests that may
65 // override time.
66 BASE_EXPORT Time TimeNowIgnoringOverride();
67 BASE_EXPORT Time TimeNowFromSystemTimeIgnoringOverride();
68 BASE_EXPORT TimeTicks TimeTicksNowIgnoringOverride();
69 BASE_EXPORT LiveTicks LiveTicksNowIgnoringOverride();
70 BASE_EXPORT ThreadTicks ThreadTicksNowIgnoringOverride();
71 BASE_EXPORT TimeTicks TimeTicksLowResolutionNowIgnoringOverride();
72 
73 #if BUILDFLAG(IS_POSIX)
74 // Equivalent to TimeTicksNowIgnoringOverride(), but is allowed to fail and
75 // return std::nullopt. This may safely be used in a signal handler.
76 BASE_EXPORT std::optional<TimeTicks> MaybeTimeTicksNowIgnoringOverride();
77 #endif
78 
79 }  // namespace subtle
80 
81 namespace internal {
82 
83 // These function pointers are used by platform-independent implementations of
84 // the Now() methods and ScopedTimeClockOverrides. They are set to point to the
85 // respective NowIgnoringOverride functions by default, but can also be set by
86 // platform-specific code to select a default implementation at runtime, thereby
87 // avoiding the indirection via the NowIgnoringOverride functions. Note that the
88 // pointers can be overridden and later reset to the NowIgnoringOverride
89 // functions by ScopedTimeClockOverrides.
90 extern std::atomic<TimeNowFunction> g_time_now_function;
91 extern std::atomic<TimeNowFunction> g_time_now_from_system_time_function;
92 extern std::atomic<TimeTicksNowFunction> g_time_ticks_now_function;
93 extern std::atomic<TimeTicksNowFunction>
94     g_time_ticks_low_resolution_now_function;
95 extern std::atomic<LiveTicksNowFunction> g_live_ticks_now_function;
96 extern std::atomic<ThreadTicksNowFunction> g_thread_ticks_now_function;
97 
98 }  // namespace internal
99 
100 }  // namespace base
101 
102 #endif  // BASE_TIME_TIME_OVERRIDE_H_
103