1*3f982cf4SFabien Sanglard // Copyright 2018 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef PLATFORM_TEST_FAKE_CLOCK_H_ 6*3f982cf4SFabien Sanglard #define PLATFORM_TEST_FAKE_CLOCK_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <atomic> 9*3f982cf4SFabien Sanglard #include <thread> 10*3f982cf4SFabien Sanglard #include <vector> 11*3f982cf4SFabien Sanglard 12*3f982cf4SFabien Sanglard #include "platform/api/time.h" 13*3f982cf4SFabien Sanglard 14*3f982cf4SFabien Sanglard namespace openscreen { 15*3f982cf4SFabien Sanglard 16*3f982cf4SFabien Sanglard class FakeTaskRunner; 17*3f982cf4SFabien Sanglard 18*3f982cf4SFabien Sanglard class FakeClock { 19*3f982cf4SFabien Sanglard public: 20*3f982cf4SFabien Sanglard explicit FakeClock(Clock::time_point start_time); 21*3f982cf4SFabien Sanglard ~FakeClock(); 22*3f982cf4SFabien Sanglard 23*3f982cf4SFabien Sanglard // Moves the clock forward, simulating execution by running tasks in all 24*3f982cf4SFabien Sanglard // FakeTaskRunners. The clock advances in one or more jumps, to ensure delayed 25*3f982cf4SFabien Sanglard // tasks see the correct "now time" when they are executed. 26*3f982cf4SFabien Sanglard void Advance(Clock::duration delta); 27*3f982cf4SFabien Sanglard 28*3f982cf4SFabien Sanglard static Clock::time_point now() noexcept; 29*3f982cf4SFabien Sanglard 30*3f982cf4SFabien Sanglard protected: 31*3f982cf4SFabien Sanglard friend class FakeTaskRunner; 32*3f982cf4SFabien Sanglard 33*3f982cf4SFabien Sanglard void SubscribeToTimeChanges(FakeTaskRunner* task_runner); 34*3f982cf4SFabien Sanglard void UnsubscribeFromTimeChanges(FakeTaskRunner* task_runner); 35*3f982cf4SFabien Sanglard 36*3f982cf4SFabien Sanglard private: 37*3f982cf4SFabien Sanglard // Used for ensuring this FakeClock's lifecycle and mutations occur on the 38*3f982cf4SFabien Sanglard // same thread. 39*3f982cf4SFabien Sanglard const std::thread::id control_thread_id_; 40*3f982cf4SFabien Sanglard 41*3f982cf4SFabien Sanglard std::vector<FakeTaskRunner*> task_runners_; 42*3f982cf4SFabien Sanglard 43*3f982cf4SFabien Sanglard // This variable is atomic because some tests (e.g., TaskRunnerImplTest) will 44*3f982cf4SFabien Sanglard // call now() on a different thread. 45*3f982cf4SFabien Sanglard static std::atomic<Clock::time_point> now_; 46*3f982cf4SFabien Sanglard }; 47*3f982cf4SFabien Sanglard 48*3f982cf4SFabien Sanglard } // namespace openscreen 49*3f982cf4SFabien Sanglard 50*3f982cf4SFabien Sanglard #endif // PLATFORM_TEST_FAKE_CLOCK_H_ 51