blob: 45c7f150a073d8489768ed7df815a37f88565880 [file] [log] [blame] [edit]
#ifndef PLATFORMS_VBMC_TIMER_TIMER_H_
#define PLATFORMS_VBMC_TIMER_TIMER_H_
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "utils/thread.h"
#include "utils/clock.h"
namespace milotic {
enum TimerState : std::uint8_t {
kIdle = 0,
kTicking,
kRestart,
kCallbackRunning,
kCallbackDone,
kEnd,
};
std::string TimerStateToString(TimerState state);
/*
* Timer
* Used to create a timer in a new thread which calls TimerCallback on timeout.
*
* Timer duration is set while calling the Start method and which can be reset
* using Restart() with the new duration.
*
* Start() should only be called once, multiple invocations will not create
* multiple timers.
* Restart() can be called multiple times before timer callback.
* Reset() ends the current timer and allows Start to be called again.
*
* TimerCallback function must be set before Start() is called.
*/
class Timer {
public:
using TimerCallback = absl::AnyInvocable<void() const>;
using Ticker = absl::AnyInvocable<void() const>;
explicit Timer(TimerCallback callback, absl::string_view timer_name = "Timer",
util::Clock* clock = util::Clock::RealClock())
: timer_name_(timer_name),
callback_(std::move(callback)),
clock_(clock) {}
~Timer();
// Not Copyable
Timer(const Timer&) = delete;
Timer& operator=(const Timer&) = delete;
// Not Movable
Timer(Timer&&) = delete;
Timer& operator=(Timer&&) = delete;
absl::Status Start(absl::Duration duration, Ticker ticker = nullptr);
absl::Status Restart(absl::Duration duration);
void Reset();
void End();
bool IsCallbackDone() {
absl::MutexLock guard(timer_mutex_);
return callback_done_;
}
bool IsRunning() {
absl::MutexLock guard(timer_mutex_);
return state_ != kIdle && state_ != kEnd;
}
private:
std::string timer_name_;
TimerCallback callback_;
std::unique_ptr<MiloticThread> tick_thread_;
absl::Mutex timer_mutex_;
util::Clock* const clock_;
absl::Duration duration_ ABSL_GUARDED_BY(timer_mutex_);
TimerState state_ ABSL_GUARDED_BY(timer_mutex_) = kIdle;
bool callback_done_ ABSL_GUARDED_BY(timer_mutex_) = false;
void Tick();
bool CheckRestartOrEnd();
bool CheckTickingOrEnd();
void CallbackWrapper();
};
} // namespace milotic
#endif // PLATFORMS_VBMC_TIMER_TIMER_H_