Fix structure in ExpiryTimer
authorChaJiwon <jw_wonny.cha@samsung.com>
Fri, 17 Jul 2015 13:27:39 +0000 (22:27 +0900)
committerUze Choi <uzchoi@samsung.com>
Fri, 17 Jul 2015 14:29:36 +0000 (14:29 +0000)
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>
service/resource-manipulation/src/common/expiryTimer/SConscript
service/resource-manipulation/src/common/expiryTimer/include/ExpiryTimer.h
service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimer.cpp
service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimerImpl.cpp [new file with mode: 0644]
service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimerImpl.h [moved from service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimer_Impl.h with 56% similarity]
service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimer_Impl.cpp [deleted file]

index de1a13b..a6bb47c 100644 (file)
@@ -56,7 +56,7 @@ if target_os == 'linux':
 ######################################################################
 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'] :
index 9a57080..e2d5b3b 100644 (file)
 #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_
index 22bc1db..19694bd 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #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()
+{
+}
diff --git a/service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimerImpl.cpp b/service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimerImpl.cpp
new file mode 100644 (file)
index 0000000..73a314d
--- /dev/null
@@ -0,0 +1,163 @@
+//******************************************************************
+//
+// 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
    {
@@ -96,8 +95,8 @@ public:
        void executorFunc(TimerCBInfo);
 
    private:
-       std::thread execute;
+       std::thread m_executorThread;
    };
 };
 
-#endif //_EXPIRY_TIMER_Impl_H_
+#endif //_EXPIRY_TIMER_IMPL_H_
diff --git a/service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimer_Impl.cpp b/service/resource-manipulation/src/common/expiryTimer/src/ExpiryTimer_Impl.cpp
deleted file mode 100644 (file)
index 5c8f352..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-//******************************************************************
-//
-// 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);
-}