Add cancelAll function and remove destroy function.
Change function name in postTimer and cancelTimer.
ExpiryTimer_Impl class change name to ExpiryTimerImpl.
Change-Id: I546e75ff52962cba248d9f9689f39f526646e57b
Signed-off-by: ChaJiwon <jw_wonny.cha@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1718
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
######################################################################
TIMER_SRC_DIR = 'src/'
timer_src = [
- TIMER_SRC_DIR + 'ExpiryTimer_Impl.cpp', TIMER_SRC_DIR + 'ExpiryTimer.cpp'
+ TIMER_SRC_DIR + 'ExpiryTimerImpl.cpp', TIMER_SRC_DIR + 'ExpiryTimer.cpp'
]
if target_os in ['tizen','android'] :
#define _EXPIRY_TIMER_H_
#include <functional>
-#include <iostream>
#include <list>
+class ExpiryTimerImpl;
+
class ExpiryTimer
{
public:
- typedef unsigned int TimerID;
- typedef std::function<void*(TimerID)> TimerCB;
- typedef long long DelayMilliSec;
+ typedef unsigned int Id;
+ typedef std::function<void(Id)> CB;
+ typedef long long DelayInMilliSec;
public:
ExpiryTimer();
~ExpiryTimer();
public:
- TimerID postTimer(DelayMilliSec sec, TimerCB);
- bool cancelTimer(TimerID timerID);
- void destroyTimer();
+ Id postTimer(DelayInMilliSec, CB); // will change name to post()
+ bool cancelTimer(Id); // will change name to cancel()
+ void destroyTimer(); // This function will be removed
+
+private:
+ void cancelAll();
private:
- std::list<TimerID> mTimerIDList;
+ std::list<Id> m_timerIDList;
+ ExpiryTimerImpl* timerPtr;
};
-#endif //_TIMER_H_
+#endif //_EXPIRY_TIMER_H_
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "ExpiryTimer.h"
-#include "ExpiryTimer_Impl.h"
-
-ExpiryTimer_Impl* timerPtr;
+#include "ExpiryTimerImpl.h"
ExpiryTimer::ExpiryTimer()
{
- timerPtr = ExpiryTimer_Impl::getInstance();
+ timerPtr = ExpiryTimerImpl::getInstance();
}
ExpiryTimer::~ExpiryTimer()
{
+ cancelAll();
}
-void ExpiryTimer::destroyTimer()
+void ExpiryTimer::cancelAll()
{
- for(auto it : mTimerIDList)
+ for(auto id : m_timerIDList)
{
- timerPtr->cancelTimer(it);
+ timerPtr->cancel(id);
}
- timerPtr->destroyInstance();
- mTimerIDList.clear();
-
- this->~ExpiryTimer();
+ m_timerIDList.clear();
}
-ExpiryTimer::TimerID ExpiryTimer::postTimer(DelayMilliSec sec, TimerCB cb)
+ExpiryTimer::Id ExpiryTimer::postTimer(DelayInMilliSec milliSec, CB cb)
{
- TimerID retID = 0;
-
- retID = timerPtr->postTimer(sec, cb);
- mTimerIDList.push_back(retID);
+ Id retID = timerPtr->post(milliSec, std::move(cb));
+ m_timerIDList.push_back(retID);
return retID;
}
-bool ExpiryTimer::cancelTimer(TimerID timerID)
+bool ExpiryTimer::cancelTimer(Id id)
{
- bool ret = false;
-
- ret = timerPtr->cancelTimer(timerID);
- mTimerIDList.remove(timerID);
+ bool ret = timerPtr->cancel(id);
+ m_timerIDList.remove(id);
return ret;
}
+
+void ExpiryTimer::destroyTimer()
+{
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "ExpiryTimerImpl.h"
+
+#include <unistd.h>
+#include <cstdlib>
+#include <utility>
+
+ExpiryTimerImpl* ExpiryTimerImpl::s_instance = nullptr;
+std::once_flag* ExpiryTimerImpl::s_flag = new std::once_flag;
+
+ExpiryTimerImpl::ExpiryTimerImpl()
+{
+ m_engine = std::default_random_engine(m_device());
+ m_checkerThread = std::thread(&ExpiryTimerImpl::runChecker, this);
+}
+
+ExpiryTimerImpl::~ExpiryTimerImpl()
+{
+ m_checkerThread.join();
+}
+
+ExpiryTimerImpl* ExpiryTimerImpl::getInstance()
+{
+ std::call_once(*s_flag, [](){ s_instance = new ExpiryTimerImpl(); });
+ return s_instance;
+}
+
+ExpiryTimerImpl::Id ExpiryTimerImpl::post(DelayInMilliSec millisec, CB cb)
+{
+ Id retID = generateId();
+
+ MilliSeconds delay(millisec);
+ insertTimerCBInfo(countExpireTime(delay), cb, retID);
+
+ return retID;
+}
+
+bool ExpiryTimerImpl::cancel(Id id)
+{
+ bool ret = false;
+ std::lock_guard<std::mutex> lockf(m_mutex);
+ for(auto it: m_timerCBList)
+ {
+ if(it.second.m_id == id)
+ {
+ if(m_timerCBList.erase(it.first)!=0)
+ ret = true;
+ else
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+void ExpiryTimerImpl::insertTimerCBInfo(ExpiredTime msec, CB cb, Id id)
+{
+ TimerCBInfo newInfo{id, cb};
+ std::lock_guard<std::mutex> lockf(m_mutex);
+ m_timerCBList.insert({msec, newInfo});
+ m_cond.notify_all();
+}
+
+ExpiryTimerImpl::ExpiredTime ExpiryTimerImpl::countExpireTime(MilliSeconds msec)
+{
+ auto now = std::chrono::system_clock::now();
+ return std::chrono::duration_cast<MilliSeconds>(now.time_since_epoch()) + msec;
+}
+
+ExpiryTimerImpl::Id ExpiryTimerImpl::generateId()
+{
+ Id retID = m_dist(m_device);
+
+ for(auto it = m_timerCBList.begin(); it != m_timerCBList.end(); )
+ {
+ if(it->second.m_id == retID || retID == 0)
+ {
+ retID = m_dist(m_device);
+ it = m_timerCBList.begin();
+ }
+ else
+ {
+ ++it;
+ }
+ }
+
+ return retID;
+}
+
+void ExpiryTimerImpl::runChecker()
+{
+ while(true)
+ {
+ std::unique_lock<std::mutex> ul(m_mutex);
+
+ if(m_timerCBList.empty())
+ {
+ m_cond.wait(ul);
+ }
+ else
+ {
+ ExpiredTime expireTime;
+ expireTime = m_timerCBList.begin()->first;
+
+ auto now = std::chrono::system_clock::now();
+ MilliSeconds waitTime = expireTime - std::chrono::duration_cast<MilliSeconds>(now.time_since_epoch());
+ m_cond.wait_for(ul, waitTime);
+
+ auto callTime = std::chrono::system_clock::now();
+ runExecutor(std::chrono::duration_cast<MilliSeconds>(callTime.time_since_epoch()));
+ }
+ }
+}
+
+void ExpiryTimerImpl::runExecutor(ExpiredTime expireTime)
+{
+ for(auto it = m_timerCBList.begin(); it != m_timerCBList.end(); ++it)
+ {
+ if(it->first <= expireTime)
+ {
+ ExecutorThread executor(it->second);
+ m_timerCBList.erase(it);
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+// ExecutorThread Class
+ExpiryTimerImpl::ExecutorThread::ExecutorThread(TimerCBInfo cbInfo)
+{
+ m_executorThread = std::thread(&ExpiryTimerImpl::ExecutorThread::executorFunc, this, cbInfo);
+}
+
+ExpiryTimerImpl::ExecutorThread::~ExecutorThread()
+{
+ m_executorThread.detach();
+}
+
+void ExpiryTimerImpl::ExecutorThread::executorFunc(TimerCBInfo cbInfo)
+{
+ cbInfo.m_cB(cbInfo.m_id);
+}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#ifndef _EXPIRY_TIMER_Impl_H_
-#define _EXPIRY_TIMER_Impl_H_
+#ifndef _EXPIRY_TIMER_IMPL_H_
+#define _EXPIRY_TIMER_IMPL_H_
-// CHECKER_WAIT_TIME : checker thread waits new request for 10 seconds
-#define CHECKER_WAIT_TIME 10
-
-#include <iostream>
#include <functional>
#include <map>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>
+#include <random>
-class ExpiryTimer_Impl
+class ExpiryTimerImpl
{
public:
typedef unsigned int Id;
- typedef std::function<void*(Id)> TimerCb;
+ typedef std::function<void(Id)> CB;
- typedef long long DelayMilliSec;
- typedef std::chrono::milliseconds milliSeconds;
- typedef std::chrono::duration<int64_t, std::milli> milliDelayTime;
+ typedef long long DelayInMilliSec;
+ typedef std::chrono::milliseconds MilliSeconds;
+ typedef std::chrono::duration<int64_t, std::milli> MilliDelayTime;
typedef std::chrono::duration<int64_t, std::milli> ExpiredTime;
private:
struct TimerCBInfo
{
Id m_id;
- TimerCb m_cb;
+ CB m_cB;
};
private:
- ExpiryTimer_Impl();
- ExpiryTimer_Impl(const ExpiryTimer_Impl&);
- ExpiryTimer_Impl& operator=(const ExpiryTimer_Impl&);
- ~ExpiryTimer_Impl();
+ ExpiryTimerImpl();
+ ExpiryTimerImpl(const ExpiryTimerImpl&) = delete;
+ ExpiryTimerImpl& operator=(const ExpiryTimerImpl&) = delete;
+ ~ExpiryTimerImpl();
public:
- static ExpiryTimer_Impl* getInstance();
+ static ExpiryTimerImpl* getInstance();
void destroyInstance();
- Id postTimer(DelayMilliSec, TimerCb);
- bool cancelTimer(Id);
+ Id post(DelayInMilliSec, CB);
+ bool cancel(Id);
private:
- Id generateID();
+ Id generateId();
- void insertTimerCBInfo(ExpiredTime, TimerCb ,Id);
- ExpiredTime countExpireTime(milliSeconds);
+ void insertTimerCBInfo(ExpiredTime, CB ,Id);
+ ExpiredTime countExpireTime(MilliSeconds);
- void createChecker();
- void doChecker();
+ void runChecker();
- void doExecutor(ExpiredTime);
+ void runExecutor(ExpiredTime);
private:
- static ExpiryTimer_Impl* s_instance;
- static std::once_flag* mflag;
+ static ExpiryTimerImpl* s_instance;
+ static std::once_flag* s_flag;
- std::multimap<ExpiredTime, TimerCBInfo> mTimerCBList;
+ std::multimap<ExpiredTime, TimerCBInfo> m_timerCBList;
- std::thread check;
+ std::thread m_checkerThread;
std::mutex m_mutex;
- std::mutex cond_mutex;
std::condition_variable m_cond;
+ std::random_device m_device;
+ std::default_random_engine m_engine;
+ std::uniform_int_distribution<Id> m_dist;
+
public:
class ExecutorThread
{
void executorFunc(TimerCBInfo);
private:
- std::thread execute;
+ std::thread m_executorThread;
};
};
-#endif //_EXPIRY_TIMER_Impl_H_
+#endif //_EXPIRY_TIMER_IMPL_H_
+++ /dev/null
-//******************************************************************
-//
-// Copyright 2015 Samsung Electronics All Rights Reserved.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "ExpiryTimer_Impl.h"
-
-#include <unistd.h>
-#include <algorithm>
-#include <cstdlib>
-#include <random>
-#include <utility>
-
-ExpiryTimer_Impl* ExpiryTimer_Impl::s_instance = nullptr;
-std::once_flag* ExpiryTimer_Impl::mflag = new std::once_flag;
-
-ExpiryTimer_Impl::ExpiryTimer_Impl()
-{
- createChecker();
-}
-
-ExpiryTimer_Impl::~ExpiryTimer_Impl()
-{
- check.detach();
- mflag = new std::once_flag;
- s_instance = nullptr;
-}
-
-void ExpiryTimer_Impl::destroyInstance()
-{
- if(mTimerCBList.empty())
- {
- try
- {
- s_instance->~ExpiryTimer_Impl();
- }
- catch(std::exception &e)
- {
- std::cout << e.what();
- }
- }
-}
-
-ExpiryTimer_Impl* ExpiryTimer_Impl::getInstance()
-{
- std::call_once((*mflag), [](){ s_instance = new ExpiryTimer_Impl(); });
- return s_instance;
-}
-
-ExpiryTimer_Impl::Id ExpiryTimer_Impl::postTimer(DelayMilliSec msec, TimerCb cb)
-{
- Id retID;
- retID = generateID();
-
- milliSeconds delay(msec);
- insertTimerCBInfo(countExpireTime(delay), cb, retID);
-
- return retID;
-}
-
-bool ExpiryTimer_Impl::cancelTimer(Id timerID)
-{
- bool ret = false;
- std::lock_guard<std::mutex> lockf(m_mutex);
- for(auto it: mTimerCBList)
- {
- if(it.second.m_id == timerID)
- {
- if(mTimerCBList.erase(it.first)!=0)
- ret = true;
- else
- ret = false;
- }
- }
- return ret;
-}
-
-void ExpiryTimer_Impl::insertTimerCBInfo(ExpiredTime msec, TimerCb cb, Id timerID)
-{
- TimerCBInfo newInfo = {timerID, cb};
- std::lock_guard<std::mutex> lockf(m_mutex);
- mTimerCBList.insert(std::multimap<ExpiredTime, TimerCBInfo>::value_type(msec, newInfo));
- m_cond.notify_all();
-}
-
-ExpiryTimer_Impl::ExpiredTime ExpiryTimer_Impl::countExpireTime(milliDelayTime msec)
-{
- auto now = std::chrono::system_clock::now();
- milliSeconds ret = std::chrono::duration_cast<milliSeconds>(now.time_since_epoch()) + msec;
-
- return ret;
-}
-
-ExpiryTimer_Impl::Id ExpiryTimer_Impl::generateID()
-{
- std::srand((unsigned)std::time(NULL));
- Id retID = std::rand();
-
- for(std::multimap<ExpiredTime, TimerCBInfo>::iterator it=mTimerCBList.begin(); it!=mTimerCBList.end(); )
- {
- if((*it).second.m_id == retID || retID == 0)
- {
- retID = std::rand();
- it = mTimerCBList.begin();
- }
- else
- {
- ++it;
- }
- }
- return retID;
-}
-
-void ExpiryTimer_Impl::createChecker()
-{
- check = std::thread(&ExpiryTimer_Impl::doChecker, this);
-}
-
-void ExpiryTimer_Impl::doChecker()
-{
- while(true)
- {
- std::unique_lock<std::mutex> ul(cond_mutex);
-
- if(mTimerCBList.empty())
- {
- m_cond.wait_for(ul, std::chrono::seconds(CHECKER_WAIT_TIME));
- }
- else
- {
- ExpiredTime expireTime;
- expireTime = mTimerCBList.begin()->first;
-
- auto now = std::chrono::system_clock::now();
- milliSeconds waitTime = expireTime - std::chrono::duration_cast<milliSeconds>(now.time_since_epoch());
- m_cond.wait_for(ul, waitTime);
-
- auto callTime = std::chrono::system_clock::now();
- doExecutor(std::chrono::duration_cast<milliSeconds>(callTime.time_since_epoch()));
- }
- }
-}
-
-void ExpiryTimer_Impl::doExecutor(ExpiredTime expireTime)
-{
- std::lock_guard<std::mutex> lockf(m_mutex);
- for(auto it: mTimerCBList)
- {
- if(it.first <= expireTime)
- {
- new ExecutorThread(it.second);
- mTimerCBList.erase(mTimerCBList.begin());
- }
- else
- break;
- }
-}
-
-// ExecutorThread Class
-ExpiryTimer_Impl::ExecutorThread::ExecutorThread(TimerCBInfo cbInfo)
-{
- execute = std::thread(&ExpiryTimer_Impl::ExecutorThread::executorFunc, this, cbInfo);
-}
-
-ExpiryTimer_Impl::ExecutorThread::~ExecutorThread()
-{
- execute.detach();
-}
-
-void ExpiryTimer_Impl::ExecutorThread::executorFunc(TimerCBInfo cbInfo)
-{
- cbInfo.m_cb(cbInfo.m_id);
-}