sled/src/sled/timer/task_queue_timeout.cc
tqcq 2b2a6101b1 feat add event_bus (#1)
Co-authored-by: tqcq <99722391+tqcq@users.noreply.github.com>
Reviewed-on: #1
2024-04-02 04:41:18 +00:00

80 lines
3.0 KiB
C++

#include "sled/timer/task_queue_timeout.h"
#include "sled/log/log.h"
#include "sled/task_queue/pending_task_safety_flag.h"
#include "sled/units/time_delta.h"
namespace sled {
TaskQueueTimeoutFactory::TaskQueueTimeout::TaskQueueTimeout(TaskQueueTimeoutFactory &parent,
sled::TaskQueueBase::DelayPrecision precision)
: parent_(parent),
precision_(precision),
safety_flag_(PendingTaskSafetyFlag::Create())
{}
TaskQueueTimeoutFactory::TaskQueueTimeout::~TaskQueueTimeout()
{
SLED_DCHECK_RUN_ON(&parent_.thread_checker_);
safety_flag_->SetNotAlive();
}
void
TaskQueueTimeoutFactory::TaskQueueTimeout::Start(DurationMs duration_ms, TimeoutID timeout_id)
{
SLED_DCHECK_RUN_ON(&parent_.thread_checker_);
ASSERT(timeout_expiration_ == std::numeric_limits<TimeMs>::max(), "");
timeout_expiration_ = parent_.get_time_() + duration_ms;
timeout_id_ = timeout_id;
if (timeout_expiration_ >= posted_task_expiration_) { return; }
if (posted_task_expiration_ != std::numeric_limits<TimeMs>::max()) {
LOGV("timer",
"New timeout duration is less than scheduled - "
"ghosting old delayed task");
safety_flag_->SetNotAlive();
safety_flag_ = PendingTaskSafetyFlag::Create();
}
posted_task_expiration_ = timeout_expiration_;
auto safety_flag = safety_flag_;
parent_.task_queue_.PostDelayedTaskWithPrecision(
precision_,
SafeTask(safety_flag_,
[timeout_id, this]() {
LOGV("timer", "Timeout expired id={}", timeout_id);
SLED_DCHECK_RUN_ON(&parent_.thread_checker_);
SLED_DCHECK(posted_task_expiration_ != std::numeric_limits<TimeMs>::max(), "");
posted_task_expiration_ = std::numeric_limits<TimeMs>::max();
if (timeout_expiration_ == std::numeric_limits<TimeMs>::max()) {
// cancelled timer
// do nothing
} else {
const TimeMs now = parent_.get_time_();
const DurationMs remaining = timeout_expiration_ - now;
bool is_expired = timeout_expiration_ <= now;
timeout_expiration_ = std::numeric_limits<TimeMs>::max();
if (!is_expired) {
// continue wait
Start(remaining, timeout_id);
} else {
LOGV("timer", "Timeout Triggered: {}", timeout_id);
parent_.on_expired_(timeout_id_);
}
}
}),
sled::TimeDelta::Millis(duration_ms));
}
void
TaskQueueTimeoutFactory::TaskQueueTimeout::Stop()
{
SLED_DCHECK_RUN_ON(&parent_.thread_checker_);
timeout_expiration_ = std::numeric_limits<TimeMs>::max();
}
}// namespace sled