1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "ExpiryTimer_Impl.h"
28 ExpiryTimer_Impl* ExpiryTimer_Impl::s_instance = nullptr;
29 std::once_flag* ExpiryTimer_Impl::mflag = new std::once_flag;
31 ExpiryTimer_Impl::ExpiryTimer_Impl()
36 ExpiryTimer_Impl::~ExpiryTimer_Impl()
44 void ExpiryTimer_Impl::destroy()
46 if(mTimerCBList.empty())
50 s_instance->~ExpiryTimer_Impl();
52 catch(std::exception &e)
54 std::cout << e.what();
58 ExpiryTimer_Impl* ExpiryTimer_Impl::getInstance()
60 std::call_once((*mflag), [](){ s_instance = new ExpiryTimer_Impl(); });
64 ExpiryTimer_Impl::Id ExpiryTimer_Impl::postTimer(DelayMilliSec msec, TimerCb cb)
69 milliSeconds delay(msec);
70 insertTimerCBInfo(countExpireTime(delay), cb, retID);
75 bool ExpiryTimer_Impl::cancelTimer(Id timerID)
78 for(auto it: mTimerCBList)
80 if(it.second.m_id == timerID)
82 std::lock_guard<std::mutex> lockf(m_mutex);
83 if(mTimerCBList.erase(it.first)!=0)
92 void ExpiryTimer_Impl::insertTimerCBInfo(ExpiredTime msec, TimerCb cb, Id timerID)
94 TimerCBInfo newInfo = {timerID, cb};
95 std::lock_guard<std::mutex> lockf(m_mutex);
96 mTimerCBList.insert(std::multimap<ExpiredTime, TimerCBInfo>::value_type(msec, newInfo));
100 ExpiryTimer_Impl::ExpiredTime ExpiryTimer_Impl::countExpireTime(milliDelayTime msec)
102 auto now = std::chrono::system_clock::now();
103 milliSeconds ret = std::chrono::duration_cast<milliSeconds>(now.time_since_epoch()) + msec;
108 ExpiryTimer_Impl::Id ExpiryTimer_Impl::generateID()
113 std::lock_guard<std::mutex> lockf(id_mutex);
114 for(std::multimap<ExpiredTime, TimerCBInfo>::iterator it=mTimerCBList.begin(); it!=mTimerCBList.end(); ++it)
116 if((*it).second.m_id == retID || retID == 0)
119 it = mTimerCBList.begin();
125 void ExpiryTimer_Impl::createChecker()
127 check = std::thread(&ExpiryTimer_Impl::doChecker, this);
130 void ExpiryTimer_Impl::doChecker()
134 std::unique_lock<std::mutex> ul(cond_mutex);
136 if(mTimerCBList.empty())
138 m_cond.wait_for(ul, std::chrono::seconds(CHECKER_WAIT_TIME));
142 ExpiredTime expireTime;
143 expireTime = mTimerCBList.begin()->first;
145 auto now = std::chrono::system_clock::now();
146 milliSeconds waitTime = expireTime - std::chrono::duration_cast<milliSeconds>(now.time_since_epoch());
147 m_cond.wait_for(ul, waitTime);
149 auto callTime = std::chrono::system_clock::now();
150 doExecutor(std::chrono::duration_cast<milliSeconds>(callTime.time_since_epoch()));
155 void ExpiryTimer_Impl::doExecutor(ExpiredTime expireTime)
157 for(auto it: mTimerCBList)
159 if(it.first <= expireTime)
161 new ExecutorThread(it.second);
162 mTimerCBList.erase(mTimerCBList.begin());
169 // ExecuterThread Class
170 ExpiryTimer_Impl::ExecutorThread::ExecutorThread(TimerCBInfo cbInfo)
172 execute = std::thread(&ExpiryTimer_Impl::ExecutorThread::executorFunc, this, cbInfo);
175 ExpiryTimer_Impl::ExecutorThread::~ExecutorThread()
180 void ExpiryTimer_Impl::ExecutorThread::executorFunc(TimerCBInfo cbInfo)
182 cbInfo.m_cb(cbInfo.m_id);