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