blob: 12fea469f4e213c161be139862fa50246c1d1b09 [file] [log] [blame] [edit]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ABS_CLOCK_CLOCK_H_
#define ABS_CLOCK_CLOCK_H_
#include <lib/zx/time.h>
#include <zircon/time.h>
#include <memory>
namespace abs_clock {
struct FakeClockState;
// An abstract clock interface.
//
// This simplifies testing code that needs access to time. Code should
// accept an abstract |Clock *| and use the provided methods.
//
// In a production, the the code should be passed an instance of
// RealClock, which uses the standard kernel-provided time mechanisms.
//
// Test code, however, can pass in a FakeClock, which allows test code
// to take control over time as required.
class Clock {
public:
virtual ~Clock() = default;
// Return the current time.
virtual zx::time Now() = 0;
// Sleep until the given deadline.
virtual void SleepUntil(zx::time deadline) = 0;
};
// A real implementation of a clock.
//
// Call "RealClock::Get()" to get a shared, global instance of the
// clock.
class RealClock final : public Clock {
public:
zx::time Now() override { return zx::time(zx_clock_get_monotonic()); }
void SleepUntil(zx::time deadline) override { zx::nanosleep(deadline); }
static RealClock* Get() {
static RealClock global_clock{};
return &global_clock;
}
private:
RealClock() = default;
};
class FakeClock : public Clock {
public:
// Create a FakeClock.
FakeClock();
FakeClock(zx::time start_time);
~FakeClock();
// Advance the time by the given duration.
void AdvanceTime(zx::duration duration);
// Clock implementation.
zx::time Now() override;
void SleepUntil(zx::time deadline) override;
private:
// State of the FakeClock.
//
// We use an opaque state pointer here to avoid exposing header
// dependencies of FakeClock on our callers.
const std::unique_ptr<FakeClockState> state_;
};
} // namespace abs_clock
#endif // ABS_CLOCK_CLOCK_H_