#pragma warning( disable : 4180 ) #include "LiveTimer.h" #include "../Utils/log.h" using namespace Flam::Common; namespace Flam { namespace Live { LiveTimer::LiveTimer() : timer(io_service,boost::posix_time::seconds(360000)) { timer.async_wait(boost::bind(&LiveTimer::TimeIsUp,this,_1)); internalThread = boost::thread(boost::ref(*this)); } LiveTimer::~LiveTimer() { io_service.stop(); internalThread.join(); } void LiveTimer::operator()() { io_service.reset(); io_service.run(); } static double GetSecondsToElapse(FlamTimeMillis callBackFlamTime,FlamTimeMillis currentFlamTime) { double secondsToElapse((callBackFlamTime-currentFlamTime)/1000); FILE_LOG(logINFO) << ": LiveTimer: Expires from now " << secondsToElapse << " A: " << callBackFlamTime << " B: " << currentFlamTime << " C: " << callBackFlamTime-currentFlamTime; if(secondsToElapse < 0) secondsToElapse = 1; else if(secondsToElapse > 3600*24) { FILE_LOG(logWARNING) << ": LiveTimer: Something is wrong. Expires from now is " << secondsToElapse; secondsToElapse = 3600*24; } return secondsToElapse; } void LiveTimer::EnqueueTimedCallback(TimerObjectPtr timerObjectPtr) { { boost::lock_guard lock(coordMutex); FILE_LOG(logINFO) << ": LiveTimer: RegisterTimedCallback " << timerObjectPtr->GetCallBackTime() << ": Locked mutex."; internalQueueMap.insert(std::make_pair(timerObjectPtr->GetCallBackTime(),timerObjectPtr)); double secondsToElapse(GetSecondsToElapse(internalQueueMap.begin()->second->GetCallBackTime(),FlamTimeMillis::GetCurrentUTCTime())); FILE_LOG(logINFO) << ": 1"; io_service.stop(); FILE_LOG(logINFO) << ": 2"; internalThread.join(); FILE_LOG(logINFO) << ": 3"; timer.expires_from_now(boost::posix_time::seconds((long)secondsToElapse)); FILE_LOG(logINFO) << ": 4"; timer.async_wait(boost::bind(&LiveTimer::TimeIsUp,this,_1)); FILE_LOG(logINFO) << ": 5"; } internalThread = boost::thread(boost::ref(*this)); FILE_LOG(logINFO) << ": LiveTimer: RegisterTimedCallback " << timerObjectPtr->GetCallBackTime() << ": Unlocked mutex."; } void LiveTimer::TimeIsUp(boost::system::error_code const& er) //Callback for asio { FILE_LOG(logINFO) << ": LiveTimer: TimeIsUp (Abort: " << (er == boost::asio::error::operation_aborted ? "true" : "false" ); if (er == boost::asio::error::operation_aborted) return; boost::mutex::scoped_lock lock(coordMutex,boost::try_to_lock_t()); if(!lock.owns_lock()) return; while(!internalQueueMap.empty() && internalQueueMap.begin()->second->GetCallBackTime()second)); //Might lead to a call of EnqueueTimedCallback... hence sep thread internalQueueMap.erase(it); } double secondsToElapse; if(internalQueueMap.empty()) secondsToElapse = 360000; else secondsToElapse = GetSecondsToElapse(internalQueueMap.begin()->second->GetCallBackTime(),FlamTimeMillis::GetCurrentUTCTime()); timer.expires_from_now(boost::posix_time::seconds((long)secondsToElapse)); timer.async_wait(boost::bind(&LiveTimer::TimeIsUp,this,_1)); } }}