fix timer
This commit is contained in:
parent
3c1b92dedb
commit
e52ec08559
@ -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,
|
||||||
|
@ -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_;
|
||||||
|
@ -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) {}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user