102 lines
2.2 KiB
C++
102 lines
2.2 KiB
C++
// TJP COPYRIGHT HEADER
|
|
|
|
//
|
|
// Timer.h
|
|
// algorithm
|
|
//
|
|
// Created by Timothy Prepscius on 1/19/18.
|
|
// Copyright © 2018 Timothy Prepscius. All rights reserved.
|
|
//
|
|
|
|
#include "SchedulerPool.hpp"
|
|
|
|
namespace timprepscius {
|
|
namespace core {
|
|
namespace time {
|
|
|
|
SchedulerPool::SchedulerPool () :
|
|
nextIndex(0)
|
|
{
|
|
}
|
|
|
|
SchedulerPool::~SchedulerPool ()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
SchedulerEventPtr SchedulerPool::schedule(const SchedulerPtr &scheduler, Time period, std::function<void()> &&f)
|
|
{
|
|
auto event = scheduler->schedule(period, true, std::move(f));
|
|
|
|
auto lock = lock_of(mutex);
|
|
events.insert(event);
|
|
|
|
return event;
|
|
}
|
|
|
|
SchedulerEventPtr SchedulerPool::once(const SchedulerPtr &scheduler, Time period, std::function<void()> &&f)
|
|
{
|
|
auto index = nextIndex++;
|
|
|
|
auto weak = weak_this(this);
|
|
|
|
// I'm locking before the schedule because, very rarely, the scheduler runs the event
|
|
// before I can put it in the map, which causes it to stay in the map forever.
|
|
// If this causes some locking problem in the future, I could also
|
|
// allocate it in the map, then schedule, and then finally, if the map still
|
|
// has the entry for it, set it - if not discard.
|
|
auto lock = lock_of(mutex);
|
|
|
|
auto event = scheduler->schedule(
|
|
period,
|
|
false,
|
|
[this, weak, f=std::move(f), index]() {
|
|
if (auto that = strong(weak))
|
|
{
|
|
remove_once(index);
|
|
f();
|
|
}
|
|
}
|
|
);
|
|
|
|
onces.emplace(index, event);
|
|
|
|
sLogDebug("core::time::SchedulerPool", logOfThis(this) << logVar(index) << logVar(onces.size()) << logVar(period) << logVar(event));
|
|
|
|
return event;
|
|
}
|
|
|
|
void SchedulerPool::remove_once_no_lock(size_t index)
|
|
{
|
|
debug_assert(mutex.locked_by_caller());
|
|
|
|
auto i = onces.find(index);
|
|
if (i != onces.end())
|
|
{
|
|
sLogDebug("core::time::SchedulerPool", logOfThis(this) << logVar(index) << logVar(onces.size()) << logVar(i->second));
|
|
|
|
onces.erase(i);
|
|
}
|
|
else
|
|
{
|
|
sLogDebug("core::time::SchedulerPool", logOfThis(this) << logVar(index) << logVar(onces.size()) << logLabel("failed"));
|
|
}
|
|
}
|
|
|
|
void SchedulerPool::remove_once(size_t index)
|
|
{
|
|
auto lock = lock_of(mutex);
|
|
remove_once_no_lock(index);
|
|
}
|
|
|
|
void SchedulerPool::clear ()
|
|
{
|
|
auto lock = lock_of(mutex);
|
|
onces.clear();
|
|
events.clear();
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace
|
|
} // namespace
|