// 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 &&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 &&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