fix timer
All checks were successful
linux-x64-gcc / linux-gcc (Release) (push) Successful in 40s
linux-x64-gcc / linux-gcc (Debug) (push) Successful in 50s

This commit is contained in:
tqcq 2024-03-11 16:49:23 +08:00
parent 3c1b92dedb
commit e52ec08559
5 changed files with 67 additions and 16 deletions

View File

@ -30,21 +30,21 @@ public:
virtual void Delete() = 0; virtual void Delete() = 0;
void PostTask(std::function<void()> &&task, inline void PostTask(std::function<void()> &&task,
const Location &location = Location::Current()) const Location &location = Location::Current())
{ {
PostTaskImpl(std::move(task), PostTaskTraits{}, location); PostTaskImpl(std::move(task), PostTaskTraits{}, location);
} }
void PostDelayedTask(std::function<void()> &&task, inline void PostDelayedTask(std::function<void()> &&task,
TimeDelta delay, TimeDelta delay,
const Location &location = Location::Current()) const Location &location = Location::Current())
{ {
PostDelayedTaskImpl(std::move(task), delay, PostDelayedTaskTraits{}, PostDelayedTaskImpl(std::move(task), delay, PostDelayedTaskTraits{},
location); location);
} }
void inline void
PostDelayedHighPrecisionTask(std::function<void()> &&task, PostDelayedHighPrecisionTask(std::function<void()> &&task,
TimeDelta delay, TimeDelta delay,
const Location &location = Location::Current()) const Location &location = Location::Current())
@ -53,7 +53,7 @@ public:
PostDelayedTaskImpl(std::move(task), delay, traits, location); PostDelayedTaskImpl(std::move(task), delay, traits, location);
} }
void inline void
PostDelayedTaskWithPrecision(DelayPrecision precision, PostDelayedTaskWithPrecision(DelayPrecision precision,
std::function<void()> &&task, std::function<void()> &&task,
TimeDelta delay, TimeDelta delay,

View File

@ -26,7 +26,7 @@ public:
const DurationMs &duration() const { return duration_; } const DurationMs &duration() const { return duration_; }
int expireation_count() const { return expiration_count_; } int expiration_count() const { return expiration_count_; }
bool is_running() const { return is_running_; } bool is_running() const { return is_running_; }
@ -38,6 +38,7 @@ private:
OnExpired on_expired, OnExpired on_expired,
UnregisterHandler unregister_handler, UnregisterHandler unregister_handler,
std::unique_ptr<Timeout> timeout); std::unique_ptr<Timeout> timeout);
void Trigger(TimerGeneration generation);
const TimerID id_; const TimerID id_;
const std::string name_; const std::string name_;

View File

@ -1,7 +1,7 @@
#include "sled/synchronization/event.h" #include "sled/synchronization/event.h"
namespace sled { namespace sled {
// constexpr TimeDelta Event::kForever; constexpr TimeDelta Event::kForever;
Event::Event() : Event(false, false) {} Event::Event() : Event(false, false) {}

View File

@ -16,6 +16,7 @@ void
TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms, TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms,
TimeoutID timeout_id) TimeoutID timeout_id)
{ {
ASSERT(timeout_expiration_ == std::numeric_limits<TimeMs>::max(), "");
timeout_expiration_ = parent_.get_time_() + duration_ms; timeout_expiration_ = parent_.get_time_() + duration_ms;
timeout_id_ = timeout_id; timeout_id_ = timeout_id;
@ -30,19 +31,25 @@ TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms,
parent_.task_queue_.PostDelayedTaskWithPrecision( parent_.task_queue_.PostDelayedTaskWithPrecision(
precision_, precision_,
[timeout_id, this]() { [timeout_id, this]() {
LOGV("timer", "Timeout expired: {}", timeout_id);
ASSERT(posted_task_expiration_
!= std::numeric_limits<TimeMs>::max(),
"");
posted_task_expiration_ = std::numeric_limits<TimeMs>::max(); posted_task_expiration_ = std::numeric_limits<TimeMs>::max();
if (timeout_expiration_ == std::numeric_limits<TimeMs>::max()) { if (timeout_expiration_ == std::numeric_limits<TimeMs>::max()) {
// cancelled timer // cancelled timer
// do nothing // do nothing
} else { } else {
DurationMs remaining = const TimeMs now = parent_.get_time_();
timeout_expiration_ - parent_.get_time_(); if (timeout_expiration_ <= now) {
timeout_expiration_ = std::numeric_limits<TimeMs>::max(); timeout_expiration_ = std::numeric_limits<TimeMs>::max();
if (remaining > 0) { LOGD("timer", "Timeout Triggered: {}", timeout_id);
Start(remaining, timeout_id);
} else {
LOGD("", "Timeout Triggered: {}", timeout_id);
parent_.on_expired_(timeout_id_); parent_.on_expired_(timeout_id_);
} else {
const DurationMs remaining = timeout_expiration_ - now;
timeout_expiration_ = std::numeric_limits<TimeMs>::max();
Start(remaining, timeout_id);
} }
} }
}, },

View File

@ -42,6 +42,40 @@ Timer::Start()
} }
} }
void
Timer::Stop()
{
if (is_running()) {
timeout_->Stop();
expiration_count_ = 0;
is_running_ = false;
}
}
void
Timer::Trigger(TimerGeneration generation)
{
if (!is_running_ || generation != generation_) { return; }
++expiration_count_;
is_running_ = false;
// if max_restarts > exppiration_count_ then restart
{
is_running_ = true;
generation_ = TimerGeneration(generation_ + 1);
timeout_->Start(duration_, MakeTimeoutId(id_, generation_));
}
sled::optional<DurationMs> new_duration = on_expired_();
if (new_duration.has_value() && new_duration != duration_) {
duration_ = new_duration.value();
if (is_running_) {
timeout_->Stop();
generation_ = TimerGeneration(generation_ + 1);
timeout_->Start(duration_, MakeTimeoutId(id_, generation_));
}
}
}
std::unique_ptr<Timer> std::unique_ptr<Timer>
TimerManager::CreateTimer(const std::string &name, Timer::OnExpired on_expired) TimerManager::CreateTimer(const std::string &name, Timer::OnExpired on_expired)
{ {
@ -57,4 +91,13 @@ TimerManager::CreateTimer(const std::string &name, Timer::OnExpired on_expired)
timers_[id] = timer.get(); timers_[id] = timer.get();
return timer; return timer;
} }
void
TimerManager::HandleTimeout(TimeoutID id)
{
TimerID timer_id = id >> 32;
TimerGeneration generation = id & 0xffffffff;
auto it = timers_.find(timer_id);
if (it != timers_.end()) { it->second->Trigger(generation); }
}
}// namespace sled }// namespace sled