Add common module that expiryTimer.
authorChaJiWon <jw_wonny.cha@samsung.com>
Fri, 3 Jul 2015 06:32:06 +0000 (15:32 +0900)
committerUze Choi <uzchoi@samsung.com>
Fri, 3 Jul 2015 07:04:10 +0000 (07:04 +0000)
check expiryTime & excute callback

destructor change to public type in ExpiryTimer.h
exclude the internal header code

Change-Id: Ic773fddaaf8332950a53eeb99e8a50a42ea75637
Signed-off-by: ChaJiWon <jw_wonny.cha@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1467
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
service/resource-manipulation/modules/common/expiryTimer/SConscript [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/include/ExpiryTimer.h [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.cpp [new file with mode: 0644]
service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.h [new file with mode: 0644]

diff --git a/service/resource-manipulation/modules/common/expiryTimer/SConscript b/service/resource-manipulation/modules/common/expiryTimer/SConscript
new file mode 100644 (file)
index 0000000..0fd1747
--- /dev/null
@@ -0,0 +1,71 @@
+#******************************************************************
+#
+# 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# ResourceCache build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+    env.AppendUnique(CCFLAGS = ['-Os'])
+    env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+timer_env = lib_env.Clone()
+
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+timer_env.AppendUnique(CPPPATH = ['include'])
+timer_env.AppendUnique(CPPPATH = ['src'])
+timer_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'libcoap'])
+
+if target_os not in ['windows', 'winrt']:
+    timer_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++11'])
+
+if target_os == 'linux':
+    timer_env.AppendUnique(LIBS = ['pthread'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+TIMER_SRC_DIR = 'src/'
+timer_src = [
+        TIMER_SRC_DIR + 'ExpiryTimer_Impl.cpp', TIMER_SRC_DIR + 'ExpiryTimer.cpp'
+        ]
+
+if target_os in ['tizen','android'] :
+    timersdk = timer_env.SharedLibrary('ExpiryTimer', timer_src)
+else :
+    timersdk = timer_env.StaticLibrary('ExpiryTimer', timer_src)
+
+timer_env.InstallTarget(timersdk, 'libExpiryTimer')
+
+# Go to build sample apps
+#SConscript('SampleApp/SConscript')
+
diff --git a/service/resource-manipulation/modules/common/expiryTimer/include/ExpiryTimer.h b/service/resource-manipulation/modules/common/expiryTimer/include/ExpiryTimer.h
new file mode 100644 (file)
index 0000000..8562a31
--- /dev/null
@@ -0,0 +1,52 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _EXPIRY_TIMER_H_
+#define _EXPIRY_TIMER_H_
+
+#include <functional>
+#include <list>
+#include <iostream>
+
+#include "ExpiryTimer_Impl.h"
+
+using namespace std;
+
+typedef unsigned int TimerID;
+typedef function<void*(TimerID)> TimerCB;
+
+class ExpiryTimer
+{
+public:
+    ExpiryTimer();
+    ~ExpiryTimer();
+
+    TimerID requestTimer(long long sec, TimerCB);
+    void cancelTimer(TimerID timerID);
+
+private:
+
+    long long countExpiredTime(long long sec);
+
+    list<TimerID> mTimerIDList;
+    ExpiryTimer_Impl* timerPtr;
+};
+
+#endif //_TIMER_H_
diff --git a/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer.cpp b/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer.cpp
new file mode 100644 (file)
index 0000000..e70cd73
--- /dev/null
@@ -0,0 +1,64 @@
+//******************************************************************
+//
+// 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.h"
+
+#include <ctime>
+
+ExpiryTimer::ExpiryTimer()
+{
+    timerPtr = ExpiryTimer_Impl::getInstance();
+}
+
+ExpiryTimer::~ExpiryTimer()
+{
+    // clear ExpiryTimer id
+    for(auto it : mTimerIDList)
+    {
+        timerPtr->cancelTimer(it);
+    }
+    mTimerIDList.clear();
+}
+
+TimerID ExpiryTimer::requestTimer(long long sec, TimerCB cb)
+{
+    TimerID retID;
+    long long expiredTime;
+
+    expiredTime = countExpiredTime(sec);
+    retID = timerPtr->requestTimer(expiredTime, cb);
+
+    mTimerIDList.push_back(retID);
+
+    return retID;
+}
+
+void ExpiryTimer::cancelTimer(TimerID timerID)
+{
+    timerPtr->cancelTimer(timerID);
+    mTimerIDList.remove(timerID);
+}
+
+long long ExpiryTimer::countExpiredTime(long long sec)
+{
+    time_t curSEC;
+    time(&curSEC);
+    return curSEC + sec;
+}
diff --git a/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.cpp b/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.cpp
new file mode 100644 (file)
index 0000000..84f489c
--- /dev/null
@@ -0,0 +1,209 @@
+//******************************************************************
+//
+// 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 <utility>
+
+
+ExpiryTimer_Impl* ExpiryTimer_Impl::s_instance = nullptr;
+std::mutex ExpiryTimer_Impl::s_mutexForCreation;
+bool ExpiryTimer_Impl::isDestroyed = false;
+
+ExpiryTimer_Impl::ExpiryTimer_Impl()
+{
+    threadNum = 0;
+    checkThreadRun = false;
+}
+
+ExpiryTimer_Impl::~ExpiryTimer_Impl()
+{
+    isDestroyed = true;
+    int status;
+
+    pthread_join(checker_th, (void **)&status);
+    pthread_detach(checker_th);
+}
+
+void ExpiryTimer_Impl::killTimer()
+{
+    s_instance->~ExpiryTimer_Impl();
+}
+
+ExpiryTimer_Impl* ExpiryTimer_Impl::getInstance()
+{
+    if(isDestroyed)
+    {
+        new(s_instance) ExpiryTimer_Impl;
+        atexit(killTimer);
+        isDestroyed = false;
+    }
+    else if(s_instance == nullptr)
+    {
+        static ExpiryTimer_Impl tmp_instance;
+        s_instance = &tmp_instance;
+    }
+    return s_instance;
+}
+
+TimerID ExpiryTimer_Impl::requestTimer(long long sec, TimerCB cb)
+{
+    if(threadNum < EXPIRY_THREAD_LIST)
+    {
+        unsigned int timerID = generateTimerID();
+        ExpiryTimer_Impl::getInstance()->registerCBTimer(sec, cb, timerID);
+        return timerID;
+    }
+    else
+        return OVERFLOW_THREAD_NUM;
+}
+
+void ExpiryTimer_Impl::cancelTimer(TimerID timerID)
+{
+    for( auto it : mTimerCBList)
+    {
+        if(it.second.m_id == timerID)
+        {
+            mTimerCBList.erase(it.first);
+            timerIDList.remove(it.second.m_id);
+        }
+    }
+}
+
+void ExpiryTimer_Impl::registerCBTimer(long long countSEC, TimerCB _cb, TimerID id)
+{
+    timerCBInfo newInfo = {id, _cb};
+    mTimerCBList.insert(multimap<long long, ExpiryTimer_Impl::timerCBInfo>::value_type(countSEC, newInfo));
+
+    if (checkThreadRun == false)
+    {
+        initThCheck();
+    }
+}
+
+void ExpiryTimer_Impl::checkTimeOut()
+{
+    while (1)
+    {
+        if(mTimerCBList.empty())
+        {
+            checkThreadRun = false;
+            break;
+        }
+       else
+        {
+           long long curSEC = getSeconds(0);
+           long long expireTime;
+           expireTime = mTimerCBList.begin()->first;
+
+           if(curSEC >= expireTime)
+           {
+               initThExecutor(mTimerCBList.begin()->second);
+               mTimerCBList.erase(mTimerCBList.begin());
+           }
+        }
+       usleep(SLEEP_TIME);
+    }
+}
+
+void* ExpiryTimer_Impl::threadChecker(void * msg)
+{
+    if(s_instance != nullptr)
+        s_instance->checkTimeOut();
+    return NULL;
+}
+
+void ExpiryTimer_Impl::initThCheck()
+{
+    int retThreadCreation;
+
+    retThreadCreation = pthread_create(&checker_th, NULL, s_instance->threadChecker, NULL);
+    if (retThreadCreation != 0)
+    {
+        return;
+    }
+    else
+    {
+        checkThreadRun = true;
+    }
+}
+
+void *ExpiryTimer_Impl::threadExecutor(void * msg)
+{
+    TimerCB cb;
+    timerCBInfo *curCBInfo;
+    curCBInfo= (timerCBInfo *) msg;
+
+    cb = curCBInfo->m_pCB;
+    cb(curCBInfo->m_id);
+
+    return NULL;
+}
+
+void ExpiryTimer_Impl::initThExecutor(timerCBInfo cbInfo)
+{
+
+    int retThreadCreation;
+    int status;
+    pthread_t executor_th;
+
+    retThreadCreation = pthread_create(&executor_th, NULL, ExpiryTimer_Impl::threadExecutor, (void *)&cbInfo);
+    threadNum++;
+
+    if (retThreadCreation != 0)
+    {
+        return;
+    }
+    else
+    {
+        pthread_join(executor_th, (void **)&status);
+        pthread_detach(executor_th);
+        threadNum--;
+    }
+}
+
+TimerID ExpiryTimer_Impl::generateTimerID()
+{
+    srand(time(NULL));
+    unsigned int retID = rand();
+
+    for(auto it : timerIDList)
+     {
+       if(it == retID || retID == 0)
+        {
+            retID = rand();
+            it = s_instance->timerIDList.front();
+        }
+     }
+    timerIDList.push_back(retID);
+
+    return retID;
+}
+
+long long ExpiryTimer_Impl::getSeconds(long long sec)
+{
+    time_t curSEC;
+    time(&curSEC);
+    long long retSEC = curSEC + sec;
+    return retSEC;
+}
diff --git a/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.h b/service/resource-manipulation/modules/common/expiryTimer/src/ExpiryTimer_Impl.h
new file mode 100644 (file)
index 0000000..5c5b526
--- /dev/null
@@ -0,0 +1,95 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _EXPIRY_TIMER_Impl_H_
+#define _EXPIRY_TIMER_Impl_H_
+
+#include <mutex>
+#include <pthread.h>
+#include <functional>
+#include <list>
+#include <map>
+#include <iostream>
+#include <new>
+
+#define EXPIRY_THREAD_LIST 50
+#define OVERFLOW_THREAD_NUM -1
+// Current checker thread design have to get checking interval.
+// SLEEP_TIME value will be removed later.
+#define SLEEP_TIME 50000
+
+using namespace std;
+
+typedef unsigned int TimerID;
+typedef function<void*(TimerID)> TimerCB;
+
+class ExpiryTimer_Impl
+{
+private:
+   struct timerCBInfo
+    {
+       TimerID m_id;
+       TimerCB m_pCB;
+    };
+
+    ExpiryTimer_Impl();
+    ExpiryTimer_Impl(const ExpiryTimer_Impl & other);
+    ~ExpiryTimer_Impl();
+
+public:
+
+     static ExpiryTimer_Impl * getInstance();
+
+    TimerID requestTimer(long long sec, TimerCB);
+    void cancelTimer(TimerID timerID);
+
+private:
+
+   static void killTimer();
+   static void *threadExecutor(void * msg);
+   static void *threadChecker(void * msg);
+
+   void registerCBTimer(long long countSEC, TimerCB _cb, TimerID id);
+   void initThCheck();
+   void initThExecutor(timerCBInfo cbInfo);
+   void checkTimeOut();
+
+   TimerID generateTimerID();
+   long long getSeconds(long long sec);
+
+public:
+
+    list<TimerID> timerIDList;
+
+private:
+
+    static ExpiryTimer_Impl * s_instance;
+    static mutex s_mutexForCreation;
+    static bool isDestroyed;
+
+    multimap<long long, timerCBInfo> mTimerCBList;
+    bool checkThreadRun;
+    list<int> mExecutorIndexList;
+    int threadNum;
+
+    pthread_t checker_th;
+    pthread_mutex_t checker_mutex;
+};
+#endif //_EXPIRY_TIMER_Impl_H_