diff --git a/src/sled/timer/timer.cc b/src/sled/timer/timer.cc index a6df078..39b5174 100644 --- a/src/sled/timer/timer.cc +++ b/src/sled/timer/timer.cc @@ -1,4 +1,5 @@ #include "sled/timer/timer.h" +#include "sled/log/log.h" namespace sled { namespace { @@ -9,6 +10,22 @@ MakeTimeoutId(TimerID timer_id, TimerGeneration generation) } }// namespace +TimerThreadDeleter::TimerThreadDeleter(TaskQueueBase *owner) : owner_(owner) {} + +void +TimerThreadDeleter::operator()(Timer *timer) +{ + if (!timer) { return; } + if (owner_) { + owner_->PostTask([timer]() { + timer->Stop(); + delete timer; + }); + } else { + delete timer; + } +} + Timer::Timer(TimerID id, const std::string &name, OnExpired on_expired, @@ -53,6 +70,20 @@ Timer::Stop() } } +void +Timer::Start(TaskQueueBase *owner) +{ + SLED_ASSERT(owner != nullptr, "owner must not be nullptr"); + owner->BlockingCall([this]() { Start(); }); +} + +void +Timer::Stop(TaskQueueBase *owner) +{ + SLED_ASSERT(owner != nullptr, "owner must not be nullptr"); + owner->BlockingCall([this]() { Stop(); }); +} + void Timer::Trigger(TimerGeneration generation) { diff --git a/src/sled/timer/timer.h b/src/sled/timer/timer.h index 85e6a24..462f74f 100644 --- a/src/sled/timer/timer.h +++ b/src/sled/timer/timer.h @@ -13,18 +13,31 @@ namespace sled { typedef uint64_t TimerID; typedef uint32_t TimerGeneration; +class Timer; + +struct TimerThreadDeleter { + TimerThreadDeleter(TaskQueueBase *owner); + inline void operator()(Timer *timer); + +private: + TaskQueueBase *owner_; +}; + class Timer { public: - using OnExpired = std::function()>; - Timer(const Timer &) = delete; + using OnExpired = std::function()>; + Timer(const Timer &) = delete; Timer &operator=(const Timer &) = delete; ~Timer(); void Start(); void Stop(); + void Start(TaskQueueBase *owner); + void Stop(TaskQueueBase *owner); + void set_duration(DurationMs duration) { duration_ = duration; } - const DurationMs &duration() const { return duration_; } + const DurationMs duration() const { return duration_; } int expiration_count() const { return expiration_count_; } @@ -46,24 +59,20 @@ private: const UnregisterHandler unregister_handler_; std::unique_ptr timeout_; - DurationMs duration_; + std::atomic duration_; TimerGeneration generation_ = TimerGeneration(0); - bool is_running_ = false; - int expiration_count_ = 0; + bool is_running_ = false; + int expiration_count_ = 0; }; class TimerManager { - using TimeoutCreator = std::function( - sled::TaskQueueBase::DelayPrecision)>; + using TimeoutCreator = std::function(sled::TaskQueueBase::DelayPrecision)>; public: - explicit TimerManager(TimeoutCreator timeout_creator) - : timeout_creator_(timeout_creator) - {} + explicit TimerManager(TimeoutCreator timeout_creator) : timeout_creator_(timeout_creator) {} - std::unique_ptr CreateTimer(const std::string &name, - Timer::OnExpired on_expired); + std::unique_ptr CreateTimer(const std::string &name, Timer::OnExpired on_expired); void HandleTimeout(TimeoutID timeout_id); private: