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"
29 ExpiryTimer_Impl* ExpiryTimer_Impl::s_instance = nullptr;
30 std::mutex ExpiryTimer_Impl::s_mutexForCreation;
31 bool ExpiryTimer_Impl::isDestroyed = false;
33 ExpiryTimer_Impl::ExpiryTimer_Impl()
36 checkThreadRun = false;
39 ExpiryTimer_Impl::~ExpiryTimer_Impl()
44 pthread_join(checker_th, (void **)&status);
45 pthread_detach(checker_th);
48 void ExpiryTimer_Impl::killTimer()
50 s_instance->~ExpiryTimer_Impl();
53 ExpiryTimer_Impl* ExpiryTimer_Impl::getInstance()
57 new(s_instance) ExpiryTimer_Impl;
61 else if(s_instance == nullptr)
63 static ExpiryTimer_Impl tmp_instance;
64 s_instance = &tmp_instance;
69 TimerID ExpiryTimer_Impl::requestTimer(long long sec, TimerCB cb)
71 if(threadNum < EXPIRY_THREAD_LIST)
73 unsigned int timerID = generateTimerID();
74 ExpiryTimer_Impl::getInstance()->registerCBTimer(sec, cb, timerID);
78 return OVERFLOW_THREAD_NUM;
81 void ExpiryTimer_Impl::cancelTimer(TimerID timerID)
83 for( auto it : mTimerCBList)
85 if(it.second.m_id == timerID)
87 mTimerCBList.erase(it.first);
88 timerIDList.remove(it.second.m_id);
93 void ExpiryTimer_Impl::registerCBTimer(long long countSEC, TimerCB _cb, TimerID id)
95 timerCBInfo newInfo = {id, _cb};
96 mTimerCBList.insert(multimap<long long, ExpiryTimer_Impl::timerCBInfo>::value_type(countSEC, newInfo));
98 if (checkThreadRun == false)
104 void ExpiryTimer_Impl::checkTimeOut()
108 if(mTimerCBList.empty())
110 checkThreadRun = false;
115 long long curSEC = getSeconds(0);
116 long long expireTime;
117 expireTime = mTimerCBList.begin()->first;
119 if(curSEC >= expireTime)
121 initThExecutor(mTimerCBList.begin()->second);
122 mTimerCBList.erase(mTimerCBList.begin());
129 void* ExpiryTimer_Impl::threadChecker(void * msg)
131 if(s_instance != nullptr)
132 s_instance->checkTimeOut();
136 void ExpiryTimer_Impl::initThCheck()
138 int retThreadCreation;
140 retThreadCreation = pthread_create(&checker_th, NULL, s_instance->threadChecker, NULL);
141 if (retThreadCreation != 0)
147 checkThreadRun = true;
151 void *ExpiryTimer_Impl::threadExecutor(void * msg)
154 timerCBInfo *curCBInfo;
155 curCBInfo= (timerCBInfo *) msg;
157 cb = curCBInfo->m_pCB;
163 void ExpiryTimer_Impl::initThExecutor(timerCBInfo cbInfo)
166 int retThreadCreation;
168 pthread_t executor_th;
170 retThreadCreation = pthread_create(&executor_th, NULL, ExpiryTimer_Impl::threadExecutor, (void *)&cbInfo);
173 if (retThreadCreation != 0)
179 pthread_join(executor_th, (void **)&status);
180 pthread_detach(executor_th);
185 TimerID ExpiryTimer_Impl::generateTimerID()
188 unsigned int retID = rand();
190 for(auto it : timerIDList)
192 if(it == retID || retID == 0)
195 it = s_instance->timerIDList.front();
198 timerIDList.push_back(retID);
203 long long ExpiryTimer_Impl::getSeconds(long long sec)
207 long long retSEC = curSEC + sec;