feat add timer

This commit is contained in:
tqcq
2024-03-07 21:10:13 +08:00
parent f6b9cc5aee
commit b94e31983b
7 changed files with 289 additions and 0 deletions

View File

@@ -53,6 +53,22 @@ public:
PostDelayedTaskImpl(std::move(task), delay, traits, location);
}
void
PostDelayedTaskWithPrecision(DelayPrecision precision,
std::function<void()> &&task,
TimeDelta delay,
const Location &location = Location::Current())
{
switch (precision) {
case DelayPrecision::kLow:
PostDelayedTask(std::move(task), delay, location);
break;
case DelayPrecision::kHigh:
PostDelayedHighPrecisionTask(std::move(task), delay, location);
break;
}
}
static TaskQueueBase *Current();
bool IsCurrent() const { return Current() == this; };

View File

@@ -0,0 +1,54 @@
#pragma once
#ifndef SLED_TIMER_QUEUE_TIMEOUT_H
#define SLED_TIMER_QUEUE_TIMEOUT_H
#include "sled/task_queue/task_queue_base.h"
#include "sled/timer/timeout.h"
#include <limits>
#include <memory>
namespace sled {
typedef uint64_t TimeMs;
class TaskQueueTimeoutFactory {
public:
TaskQueueTimeoutFactory(
sled::TaskQueueBase &task_queue,
std::function<TimeMs()> get_time,
std::function<void(TimeoutID timeout_id)> on_expired)
: task_queue_(task_queue),
get_time_(get_time),
on_expired_(on_expired)
{}
std::unique_ptr<Timeout>
CreateTimeout(sled::TaskQueueBase::DelayPrecision precision =
sled::TaskQueueBase::DelayPrecision::kHigh)
{
return std::unique_ptr<TaskQueueTimeout>(
new TaskQueueTimeout(*this, precision));
}
private:
class TaskQueueTimeout : public Timeout {
public:
TaskQueueTimeout(TaskQueueTimeoutFactory &parent,
sled::TaskQueueBase::DelayPrecision precision);
~TaskQueueTimeout() override;
void Start(DurationMs duration, TimeoutID timeout_id) override;
void Stop() override;
private:
TaskQueueTimeoutFactory &parent_;
const sled::TaskQueueBase::DelayPrecision precision_;
TimeMs posted_task_expiration_ = std::numeric_limits<TimeMs>::max();
TimeMs timeout_expiration_ = std::numeric_limits<TimeMs>::max();
TimeoutID timeout_id_ = TimeoutID(0);
};
sled::TaskQueueBase &task_queue_;
const std::function<TimeMs()> get_time_;
const std::function<void(TimeoutID)> on_expired_;
};
}// namespace sled
#endif// SLED_TIMER_QUEUE_TIMEOUT_H

View File

@@ -0,0 +1,25 @@
#pragma once
#ifndef SLED_TIMER_TIMEOUT_H
#define SLED_TIMER_TIMEOUT_H
#include <stdint.h>
namespace sled {
typedef uint32_t DurationMs;
typedef uint64_t TimeoutID;
class Timeout {
public:
virtual ~Timeout() = default;
virtual void Start(DurationMs duration, TimeoutID timeout_id) = 0;
virtual void Stop() = 0;
virtual void Restart(DurationMs duration, TimeoutID timeout_id)
{
Stop();
Start(duration, timeout_id);
}
};
}// namespace sled
//
#endif// SLED_TIMER_TIMEOUT_H

View File

@@ -0,0 +1,74 @@
#pragma once
#ifndef SLED_TIMER_TIMER_H
#define SLED_TIMER_TIMER_H
#include "timeout.h"
#include <map>
#include <memory>
#include <sled/optional.h>
#include <sled/task_queue/task_queue_base.h>
#include <stdint.h>
namespace sled {
typedef uint64_t TimerID;
typedef uint32_t TimerGeneration;
class Timer {
public:
using OnExpired = std::function<sled::optional<DurationMs>()>;
Timer(const Timer &) = delete;
Timer &operator=(const Timer &) = delete;
~Timer();
void Start();
void Stop();
void set_duration(DurationMs duration) { duration_ = duration; }
const DurationMs &duration() const { return duration_; }
int expireation_count() const { return expiration_count_; }
bool is_running() const { return is_running_; }
private:
friend class TimerManager;
using UnregisterHandler = std::function<void()>;
Timer(TimerID id,
const std::string &name,
OnExpired on_expired,
UnregisterHandler unregister_handler,
std::unique_ptr<Timeout> timeout);
const TimerID id_;
const std::string name_;
const OnExpired on_expired_;
const UnregisterHandler unregister_handler_;
std::unique_ptr<Timeout> timeout_;
DurationMs duration_;
TimerGeneration generation_ = TimerGeneration(0);
bool is_running_ = false;
int expiration_count_ = 0;
};
class TimerManager {
using TimeoutCreator = std::function<std::unique_ptr<Timeout>(
sled::TaskQueueBase::DelayPrecision)>;
public:
explicit TimerManager(TimeoutCreator timeout_creator)
: timeout_creator_(timeout_creator)
{}
std::unique_ptr<Timer> CreateTimer(const std::string &name,
Timer::OnExpired on_expired);
void HandleTimeout(TimeoutID timeout_id);
private:
const TimeoutCreator timeout_creator_;
std::map<TimerID, Timer *> timers_;
TimerID next_id_ = TimerID(0);
};
}// namespace sled
#endif// SLED_TIMER_TIMER_H