Merge branch 'master' of https://code.uocat.com/tqcq/sled
Some checks failed
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 1m16s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Failing after 1m28s
linux-arm-gcc / linux-gcc-armhf (push) Failing after 1m30s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Failing after 1m55s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Failing after 2m16s
linux-x64-gcc / linux-gcc (Release) (push) Failing after 2m16s
Some checks failed
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 1m16s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Failing after 1m28s
linux-arm-gcc / linux-gcc-armhf (push) Failing after 1m30s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Failing after 1m55s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (push) Failing after 2m16s
linux-x64-gcc / linux-gcc (Release) (push) Failing after 2m16s
This commit is contained in:
commit
4fe83af09d
@ -8,6 +8,7 @@
|
|||||||
#define SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H
|
#define SLED_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "sled/meta/type_traits.h"
|
||||||
#include "sled/ref_counted_base.h"
|
#include "sled/ref_counted_base.h"
|
||||||
#include "sled/scoped_refptr.h"
|
#include "sled/scoped_refptr.h"
|
||||||
#include "sled/synchronization/sequence_checker.h"
|
#include "sled/synchronization/sequence_checker.h"
|
||||||
@ -53,11 +54,22 @@ private:
|
|||||||
scoped_refptr<PendingTaskSafetyFlag> flag_;
|
scoped_refptr<PendingTaskSafetyFlag> flag_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::function<void()>
|
template<typename F, typename... Args, typename = EnableIfT<!std::is_void<InvokeResultT<F, Args...>>::value>>
|
||||||
SafeTask(scoped_refptr<PendingTaskSafetyFlag> flag, std::function<void()> task)
|
std::function<InvokeResultT<F, Args...>(Args &&...)>
|
||||||
|
SafeTask(scoped_refptr<PendingTaskSafetyFlag> flag, F &&f)
|
||||||
{
|
{
|
||||||
return [flag, task]() mutable {
|
return [flag, f](Args &&...args) mutable -> InvokeResultT<F, Args...> {
|
||||||
if (flag->alive()) { std::move(task)(); }
|
if (flag->alive()) { return f(std::forward<Args>(args)...); }
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F, typename... Args, typename = EnableIfT<std::is_void<InvokeResultT<F, Args...>>::value>>
|
||||||
|
std::function<void(Args &&...)>
|
||||||
|
SafeTask(scoped_refptr<PendingTaskSafetyFlag> flag, F &&f)
|
||||||
|
{
|
||||||
|
return [flag, f](Args &&...args) mutable -> void {
|
||||||
|
if (flag->alive()) { f(std::forward<Args>(args)...); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "sled/timer/timer.h"
|
#include "sled/timer/timer.h"
|
||||||
|
#include "sled/log/log.h"
|
||||||
|
|
||||||
namespace sled {
|
namespace sled {
|
||||||
namespace {
|
namespace {
|
||||||
@ -9,6 +10,22 @@ MakeTimeoutId(TimerID timer_id, TimerGeneration generation)
|
|||||||
}
|
}
|
||||||
}// namespace
|
}// 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,
|
Timer::Timer(TimerID id,
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
OnExpired on_expired,
|
OnExpired on_expired,
|
||||||
@ -47,12 +64,26 @@ Timer::Stop()
|
|||||||
{
|
{
|
||||||
if (is_running()) {
|
if (is_running()) {
|
||||||
timeout_->Stop();
|
timeout_->Stop();
|
||||||
generation_ = TimerGeneration(generation_ + 1);
|
generation_ = TimerGeneration(generation_ + 1);
|
||||||
expiration_count_ = 0;
|
expiration_count_ = 0;
|
||||||
is_running_ = false;
|
is_running_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
Timer::Trigger(TimerGeneration generation)
|
Timer::Trigger(TimerGeneration generation)
|
||||||
{
|
{
|
||||||
@ -81,23 +112,26 @@ Timer::Trigger(TimerGeneration 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)
|
||||||
{
|
{
|
||||||
next_id_ = TimerID(next_id_ + 1);
|
next_id_ = TimerID(next_id_ + 1);
|
||||||
TimerID id = next_id_;
|
TimerID id = next_id_;
|
||||||
|
|
||||||
std::unique_ptr<Timeout> timeout = timeout_creator_(sled::TaskQueueBase::DelayPrecision::kHigh);
|
std::unique_ptr<Timeout> timeout = timeout_creator_(sled::TaskQueueBase::DelayPrecision::kHigh);
|
||||||
auto timer = std::unique_ptr<Timer>(new Timer(
|
auto timer = std::unique_ptr<Timer>(new Timer(
|
||||||
id, name, std::move(on_expired),
|
id,
|
||||||
/* ungrgister_handler=*/[this, id]() { timers_.erase(id); }, std::move(timeout)));
|
name,
|
||||||
timers_[id] = timer.get();
|
std::move(on_expired),
|
||||||
|
/* ungrgister_handler=*/[this, id]() { timers_.erase(id); },
|
||||||
|
std::move(timeout)));
|
||||||
|
timers_[id] = timer.get();
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TimerManager::HandleTimeout(TimeoutID id)
|
TimerManager::HandleTimeout(TimeoutID id)
|
||||||
{
|
{
|
||||||
TimerID timer_id = id >> 32;
|
TimerID timer_id = id >> 32;
|
||||||
TimerGeneration generation = id & 0xffffffff;
|
TimerGeneration generation = id & 0xffffffff;
|
||||||
auto it = timers_.find(timer_id);
|
auto it = timers_.find(timer_id);
|
||||||
if (it != timers_.end()) { it->second->Trigger(generation); }
|
if (it != timers_.end()) { it->second->Trigger(generation); }
|
||||||
}
|
}
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
@ -13,18 +13,31 @@ namespace sled {
|
|||||||
typedef uint64_t TimerID;
|
typedef uint64_t TimerID;
|
||||||
typedef uint32_t TimerGeneration;
|
typedef uint32_t TimerGeneration;
|
||||||
|
|
||||||
|
class Timer;
|
||||||
|
|
||||||
|
struct TimerThreadDeleter {
|
||||||
|
TimerThreadDeleter(TaskQueueBase *owner);
|
||||||
|
inline void operator()(Timer *timer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskQueueBase *owner_;
|
||||||
|
};
|
||||||
|
|
||||||
class Timer {
|
class Timer {
|
||||||
public:
|
public:
|
||||||
using OnExpired = std::function<sled::optional<DurationMs>()>;
|
using OnExpired = std::function<sled::optional<DurationMs>()>;
|
||||||
Timer(const Timer &) = delete;
|
Timer(const Timer &) = delete;
|
||||||
Timer &operator=(const Timer &) = delete;
|
Timer &operator=(const Timer &) = delete;
|
||||||
~Timer();
|
~Timer();
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
void Start(TaskQueueBase *owner);
|
||||||
|
void Stop(TaskQueueBase *owner);
|
||||||
|
|
||||||
void set_duration(DurationMs duration) { duration_ = duration; }
|
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_; }
|
int expiration_count() const { return expiration_count_; }
|
||||||
|
|
||||||
@ -46,24 +59,20 @@ private:
|
|||||||
const UnregisterHandler unregister_handler_;
|
const UnregisterHandler unregister_handler_;
|
||||||
std::unique_ptr<Timeout> timeout_;
|
std::unique_ptr<Timeout> timeout_;
|
||||||
|
|
||||||
DurationMs duration_;
|
std::atomic<DurationMs> duration_;
|
||||||
|
|
||||||
TimerGeneration generation_ = TimerGeneration(0);
|
TimerGeneration generation_ = TimerGeneration(0);
|
||||||
bool is_running_ = false;
|
bool is_running_ = false;
|
||||||
int expiration_count_ = 0;
|
int expiration_count_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TimerManager {
|
class TimerManager {
|
||||||
using TimeoutCreator = std::function<std::unique_ptr<Timeout>(
|
using TimeoutCreator = std::function<std::unique_ptr<Timeout>(sled::TaskQueueBase::DelayPrecision)>;
|
||||||
sled::TaskQueueBase::DelayPrecision)>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TimerManager(TimeoutCreator timeout_creator)
|
explicit TimerManager(TimeoutCreator timeout_creator) : timeout_creator_(timeout_creator) {}
|
||||||
: timeout_creator_(timeout_creator)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::unique_ptr<Timer> CreateTimer(const std::string &name,
|
std::unique_ptr<Timer> CreateTimer(const std::string &name, Timer::OnExpired on_expired);
|
||||||
Timer::OnExpired on_expired);
|
|
||||||
void HandleTimeout(TimeoutID timeout_id);
|
void HandleTimeout(TimeoutID timeout_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user