BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
59a5601
Branches
Tags
master
Blinker
src
common
CallMgr.cpp
fix erasing and processing time events
Stefan Schuermans
commited
59a5601
at 2018-09-09 16:22:42
CallMgr.cpp
Blame
History
Raw
/* Blinker Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <map> #include <set> #include "CallMgr.h" #include "Io.h" #include "IoCallee.h" #include "Time.h" #include "TimeCallee.h" namespace Blinker { /// constructor CallMgr::CallMgr() { } /// destructor CallMgr::~CallMgr() { } /** * @brief cancel callback at read I/O event * @param[in] callee whom not to call * @param[in] io I/O object not to monitor for readability any more */ void CallMgr::cancelIoReadCall(IoCallee *callee, Io *io) { // remove callee for this I/O object IoCallees &callees = m_iosRead[io]; callees.erase(callee); // no more callees -> remove I/O object if (callees.empty()) m_iosRead.erase(io); } /** * @brief request callback at read I/O event * @param[in] callee whom to call * @param[in] io I/O object to monitor for readability */ void CallMgr::requestIoReadCall(IoCallee *callee, Io *io) { m_iosRead[io].insert(callee); } /** * @brief cancel callback at write I/O event * @param[in] callee whom not to call * @param[in] io I/O object not to monitor for writability any more */ void CallMgr::cancelIoWriteCall(IoCallee *callee, Io *io) { // remove callee for this I/O object IoCallees &callees = m_iosWrite[io]; callees.erase(callee); // no more callees -> remove I/O object if (callees.empty()) m_iosWrite.erase(io); } /** * @brief request callback at write I/O event * @param[in] callee whom to call * @param[in] io I/O object to monitor for writability */ void CallMgr::requestIoWriteCall(IoCallee *callee, Io *io) { m_iosWrite[io].insert(callee); } /** * @brief cancel callback at certain time * @param[in] callee whom not to call */ void CallMgr::cancelTimeCall(TimeCallee *callee) { // find time a call is registered at TimeCalleeMap::iterator itCallee; itCallee = m_timeCallees.find(callee); if (itCallee == m_timeCallees.end()) return; // no call registered const Time &time = itCallee->second; // remove registered call m_times[time].erase(callee); m_timeCallees.erase(itCallee); } /** * @brief request callback at certain time * @param[in] callee whom to call * @param[in] time when to call * * this cancels a previous time call request from callee */ void CallMgr::requestTimeCall(TimeCallee *callee, const Time &time) { // cancel previous call cancelTimeCall(callee); // register call at new time m_times[time].insert(callee); m_timeCallees[callee] = time; } /// run call manager void CallMgr::run() { while (!m_times.empty() || !m_iosRead.empty() || !m_iosWrite.empty()) { // get time until first call time Time timeout; if (!m_times.empty()) { timeout = m_times.begin()->first - Time::now(); } else { timeout.fromMs(100); } // time already passed or reached if (timeout <= Time::zero) { // get time callees and remove entry from time map TimeCallees timeCallees = m_times.begin()->second; m_times.erase(m_times.begin()); // call time callees TimeCallees::const_iterator itTC; for (itTC = timeCallees.begin(); itTC != timeCallees.end(); ) { TimeCallees::const_iterator itTCE = itTC; // save iterator for erase TimeCallee *tc = *itTC; // save pointer to time callee for callback itTC++; // advance loop iterator to next element m_timeCallees.erase(*itTCE); // first remove request from callee map tc->timeCall(); // then call callee } } // if timeout // wait for I/O events IoMap::const_iterator itM; Io::Set rd, wr; for (itM = m_iosRead.begin(); itM != m_iosRead.end(); ++itM) rd.insert(itM->first); for (itM = m_iosWrite.begin(); itM != m_iosWrite.end(); ++itM) wr.insert(itM->first); Io::wait(rd, wr, timeout); // call I/O callees with pending events Io::Set::const_iterator itS; IoCallees::const_iterator itIC; for (itS = rd.begin(); itS != rd.end(); ++itS) { const IoCallees &ioCallees = m_iosRead[*itS]; for (itIC = ioCallees.begin(); itIC != ioCallees.end(); ++itIC) (*itIC)->ioReadCall(*itS); } for (itS = wr.begin(); itS != wr.end(); ++itS) { const IoCallees &ioCallees = m_iosWrite[*itS]; for (itIC = ioCallees.begin(); itIC != ioCallees.end(); ++itIC) (*itIC)->ioWriteCall(*itS); } } // while m_times m_iosRead m_iosWrite } } // namespace Blinker