[SSM] Modify thread util and framework init method
authorjk13 <jihyeok13.kim@samsung.com>
Mon, 17 Nov 2014 11:11:03 +0000 (20:11 +0900)
committerjk13 <jihyeok13.kim@samsung.com>
Mon, 17 Nov 2014 11:11:03 +0000 (20:11 +0900)
Problem: Thread worker crashes while terminating.
         SoftSensor searching path must given at compile time

How:     Rearchitecture threading model
         Add XML descriptor based framework initialization.
           1. Search SoftSensorDescription.xml
              (previously high-context.xml) where executable located
           2. Or put search path using below init configration.

<SSMCore>
    <Device>
        <UDN>abcde123-31f8-11b4-a222-08002b34c003</UDN>
        <Name>MyPC</Name>
        <Type>PC</Type>
    </Device>
    <Config>
        <SoftSensorRepository>/usr/local/SSRepo/</SoftSensorRepository>
        <SoftSensorDescription>/usr/local/SSRepo/SSDescription.xml</SoftSensorDescription>
    </Config>
</SSMCore>

Change-Id: Id2c0746357d9e850e9e90016547b116412b758d2
Signed-off-by: Kim Jee Hyeok <jihyeok13.kim@samsung.com>
22 files changed:
service/soft-sensor-manager/SSMCore/src/Common/InternalInterface.h
service/soft-sensor-manager/SSMCore/src/Common/PlatformLayer.h
service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.cpp [new file with mode: 0644]
service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.h
service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.h
service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.h
service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.h
service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.h
service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp
service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.h
service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.cpp
service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.h
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.h
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.h
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp
service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h

index 774a74e..6da528e 100644 (file)
@@ -116,15 +116,16 @@ public:
        * @brief        set device information
        *
        * @param        [in] std::string name - Device name
-       * @param        [in] std::string udn - Device UUID
        * @param        [in] std::string type - Device Type
+       * @param        [in] std::string pathSoftSensors - SoftSensors Repository path
+       * @param        [in] std::string pathDescription - SoftSensors Description path
        * @return       void
        *
-       * @warning      
-       * @exception    
-       * @see          
+       * @warning
+       * @exception
+       * @see
        */
-       virtual void setCurrentDeviceInfo(IN std::string name, IN IN std::string type) = 0;
+       virtual void setCurrentDeviceInfo(IN std::string name, IN std::string type, IN std::string pathSoftSensors, IN std::string pathDescription) = 0;
 
        virtual SSMRESULT registerResourceFinderEvent(IN IResourceEvent *pResourceEvent) = 0;
        virtual SSMRESULT startResourceFinder() = 0;
@@ -133,6 +134,9 @@ public:
 
        virtual SSMRESULT startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent) = 0;
        virtual SSMRESULT stopObserveResource(IN ISSMResource *pSensor) = 0;
+
+       virtual SSMRESULT loadSoftSensor(IN std::string softSensorName, IN ICtxDelegate *pDelegate, OUT void **hSoftSensor) = 0;
+       virtual SSMRESULT unloadSoftSensor(IN void *hSoftSensor) = 0;
 };
 
 struct ModelProperty
index 514351c..a102ee7 100644 (file)
@@ -20,6 +20,9 @@
 
 #if defined(WIN32)
 #include <Windows.h>
+#include <Shlwapi.h>
+
+#pragma comment(lib, "Shlwapi.lib")
 #pragma comment(lib, "../Outputs/sqlite3.lib")
 
 #elif defined(LINUX)
@@ -28,6 +31,7 @@
 #include <sys/time.h>
 #include <deque>
 #include <dlfcn.h>
+#include <semaphore.h>
 
 #elif defined(ANDROID)
 #include <android/log.h>
 
 #endif
 
-#if defined(WIN32)
-
-#define MODEL_DIRECTORY "../Outputs/"
-
-#define HIGH_LOCATION "../Outputs/HighContextDictionary.xml"
-#define USER_DATA_LOCATION "../Outputs/UserDataDictionary.xml"
+#define DEFAULT_PATH_SOFT_SENSORS "SoftSensorDescription.xml"
 
 //#define LOCATION_SSM_DB_DUMP "myBackup.db"
 #define LOCATION_SSM_DB_DUMP ""
 
-#elif defined(TIZEN)
-
-#define MODEL_DIRECTORY "/home/developer/ssm/"
-
-#define HIGH_LOCATION "/home/developer/ssm/HighContextDictionary.xml"
-#define LOW_LOCATION "/home/developer/ssm/LowContextDictionary.xml"
-#define SENSOR_LOCATION "/home/developer/ssm/SensorDictionary.xml"
-#define USER_DATA_LOCATION "/home/developer/ssm/UserDataDictionary.xml"
-
-#define LOCATION_SSM_DB_DUMP ""
-
-#elif defined(ANDROID)
-
-#define MODEL_DIRECTORY "/data/data/com.sec.android.ssmcore/files/"
-
-#define HIGH_LOCATION "/data/data/com.sec.android.ssmcore/files/HighContextDictionary.xml"
-#define LOW_LOCATION "/data/data/com.sec.android.ssmcore/files/LowContextDictionary.xml"
-#define SENSOR_LOCATION "/data/data/com.sec.android.ssmcore/files/SensorDictionary.xml"
-#define USER_DATA_LOCATION "/data/data/com.sec.android.ssmcore/files/UserDataDictionary.xml"
-
-#define LOCATION_SSM_DB_DUMP ""
-
-#elif defined(LINUX)
-
-//#define MODEL_DIRECTORY "/home/iotivity/Desktop/Project/Iotivity-Candidate/oic-service/Data_Management/SoftSensorManager/Outputs/"
-
-//#define HIGH_LOCATION "/home/iotivity/Desktop/Project/Iotivity-Candidate/oic-service/Data_Management/SoftSensorManager/Outputs/HighContextDictionary.xml"
-#define LOW_LOCATION "/home/iotivity/Desktop/LowContextDictionary.xml"
-#define SENSOR_LOCATION "/home/iotivity/Desktop/SensorDictionary.xml"
-#define USER_DATA_LOCATION "/home/iotivity/Desktop/UserDataDictionary.xml"
-
-#define LOCATION_SSM_DB_DUMP ""
-
-#endif
-
 #if defined(WIN32) || defined(LINUX)
 
 #define REPORT_MESSAGE(tag, msg) {printf("[%s] %s\n", tag, msg);}
-#define LOGV(...)  printf(__VA_ARGS__)
-#define LOGW(...)  printf(__VA_ARGS__)
-#define LOGE(...)  printf(__VA_ARGS__)
 
 #define SSM_VOID_ASSERT(Exp, STRErrorMsg) \
        { \
 
 void ReportMessage(const char *tag, const char *msg);
 #define REPORT_MESSAGE(tag, msg) {ReportMessage(tag, msg);}
-#define LOG_TAG2 "JACK"
-#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG2, __VA_ARGS__)
-#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG2, __VA_ARGS__)
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG2, __VA_ARGS__)
 
 #define SSM_VOID_ASSERT(Exp, STRErrorMsg) \
        { \
@@ -199,10 +156,6 @@ void ReportMessage(const char *tag, const char *msg);
        }
 
 #elif defined(TIZEN)
-
-#define LOGV(...)  AppLog(__VA_ARGS__)
-#define LOGW(...)  AppLog(__VA_ARGS__)
-#define LOGE(...)  AppLog(__VA_ARGS__)
 #define REPORT_MESSAGE(tag, msg)
 
 #define SSM_VOID_ASSERT(Exp, STRErrorMsg) \
diff --git a/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.cpp b/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.cpp
new file mode 100644 (file)
index 0000000..8ab9b07
--- /dev/null
@@ -0,0 +1,361 @@
+#include "ThreadManager.h"
+
+CSimpleMutex::CSimpleMutex()
+{
+#if defined(WIN32)
+       InitializeCriticalSection(&m_criticalSection);
+#elif defined(LINUX)
+       pthread_mutexattr_init(&m_mutexAttribute);
+       pthread_mutexattr_settype(&m_mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
+       pthread_mutex_init(&m_mutex, &m_mutexAttribute);
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+}
+
+CSimpleMutex::~CSimpleMutex()
+{
+#if defined(WIN32)
+       DeleteCriticalSection(&m_criticalSection);
+#elif defined(LINUX)
+       pthread_mutex_destroy(&m_mutex);
+       pthread_mutexattr_destroy(&m_mutexAttribute);
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+}
+
+void CSimpleMutex::lock()
+{
+#if defined(WIN32)
+       EnterCriticalSection(&m_criticalSection);
+#elif defined(LINUX)
+       pthread_mutex_lock(&m_mutex);
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+}
+
+void CSimpleMutex::unlock()
+{
+#if defined(WIN32)
+       LeaveCriticalSection(&m_criticalSection);
+#elif defined(LINUX)
+       pthread_mutex_unlock(&m_mutex);
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+}
+
+
+CSemaphore::CSemaphore()
+{
+}
+
+CSemaphore::~CSemaphore()
+{
+}
+
+SSMRESULT CSemaphore::initialize()
+{
+#if defined(WIN32)
+       hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
+
+       if (hSemaphore == NULL)
+               return SSM_E_FAIL;
+#elif defined(LINUX)
+       if (sem_init(&hSemaphore, 0, 0) == -1)
+               return SSM_E_FAIL;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+       return SSM_S_OK;
+}
+
+SSMRESULT CSemaphore::destroy()
+{
+#if defined(WIN32)
+       if (CloseHandle(hSemaphore) == FALSE)
+               return SSM_E_FAIL;
+#elif defined(LINUX)
+       if (sem_destroy(&hSemaphore) == -1)
+               return SSM_E_FAIL;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+       return SSM_S_OK;
+}
+
+SSMRESULT CSemaphore::take()
+{
+#if defined(WIN32)
+       if (WaitForSingleObject(hSemaphore, INFINITE) == WAIT_OBJECT_0)
+               return SSM_S_OK;
+
+       return SSM_E_FAIL;
+#elif defined(LINUX)
+       if (sem_wait(&hSemaphore) == -1)
+               return SSM_E_FAIL;
+
+       return SSM_S_OK;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+}
+
+SSMRESULT CSemaphore::give()
+{
+#if defined(WIN32)
+       if (ReleaseSemaphore(hSemaphore, 1, NULL) != 0)
+               return SSM_S_OK;
+
+       return SSM_E_FAIL;
+#elif defined(LINUX)
+       if (sem_post(&hSemaphore) == -1)
+               return SSM_E_FAIL;
+
+       return SSM_S_OK;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+}
+
+
+bool CWorkerThread::getTask(ClientEntry *clientEntry)
+{
+       m_mtxClientEntry.lock();
+       //Check empty
+       if (m_ClientEntry.empty())
+       {
+               m_mtxClientEntry.unlock();
+               //Sleep if there are no more tasks
+               m_semTask.take();
+       }
+       else
+       {
+               m_mtxClientEntry.unlock();
+       }
+
+       //Check destroy
+       m_mtxThreadTerm.lock();
+       if (m_bThreadTerm == true)
+       {
+               m_mtxThreadTerm.unlock();
+               return false;
+       }
+       m_mtxThreadTerm.unlock();
+
+       m_mtxClientEntry.lock();
+       if (!m_ClientEntry.empty())
+       {
+               *clientEntry = m_ClientEntry.front();
+               m_ClientEntry.pop_front();
+       }
+       m_mtxClientEntry.unlock();
+
+       return true;
+}
+
+void CWorkerThread::worker()
+{
+       ClientEntry clientEntry;
+
+       m_semTask.initialize();
+
+       //Thread Creation completed
+       m_semInit.give();
+
+       //Wait for any tasks
+       while (getTask(&clientEntry))
+       {
+               if (clientEntry.pClient)
+               {
+                       clientEntry.pClient->onExecute(clientEntry.pArg);
+                       clientEntry.pClient->onTerminate(clientEntry.pArg);
+               }
+               SAFE_RELEASE(clientEntry.pClient);
+       }
+
+       //Clean all remaining tasks
+       m_mtxClientEntry.lock();
+       //Remove all tasks from queue
+       for (std::list<ClientEntry>::iterator itor = m_ClientEntry.begin();
+               itor != m_ClientEntry.end(); ++itor)
+       {
+               ClientEntry clientEntry = *itor;
+               clientEntry.pClient->onTerminate(clientEntry.pArg);
+               SAFE_RELEASE(clientEntry.pClient);
+       }
+       m_ClientEntry.clear();
+       m_mtxClientEntry.unlock();
+
+       m_semTask.destroy();
+
+       m_semTerm.give();
+}
+
+SSMRESULT CWorkerThread::initialize()
+{
+       SSMRESULT res = SSM_E_FAIL;
+
+       //Create thread and wait for jobs
+#if defined(WIN32)
+       m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_worker,
+               this, 0, NULL);
+
+       if (m_hThread == NULL)
+       {
+               return SSM_E_FAIL;
+       }
+#elif defined(LINUX)
+       if (pthread_create(&m_hThread, NULL, (void*(*)(void*))_worker, (void*)this) != 0)
+       {
+               return SSM_E_FAIL;
+       }
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+       //Wait till thread created
+       SSM_CLEANUP_ASSERT(m_semInit.take());
+       SSM_CLEANUP_ASSERT(m_semInit.destroy());
+
+CLEANUP:
+       return res;
+}
+
+SSMRESULT CWorkerThread::terminate()
+{
+       SSMRESULT res = SSM_E_FAIL;
+
+       //Let worker destroyed
+       m_mtxThreadTerm.lock();
+       m_bThreadTerm = true;
+       m_mtxThreadTerm.unlock();
+
+       SSM_CLEANUP_ASSERT(m_semTask.give());
+
+       SSM_CLEANUP_ASSERT(m_semTerm.take());
+       SSM_CLEANUP_ASSERT(m_semTerm.destroy());
+
+#if defined(WIN32)
+       if (m_hThread != NULL)
+       {
+               CloseHandle(m_hThread);
+       }
+#elif defined(LINUX)
+       pthread_detach(m_hThread);
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+       res = SSM_S_OK;
+
+CLEANUP:
+       return res;
+}
+
+SSMRESULT CWorkerThread::finalConstruct()
+{
+       SSMRESULT       res = SSM_E_FAIL;
+
+       m_bThreadTerm = false;
+
+       SSM_CLEANUP_ASSERT(m_semInit.initialize());
+       SSM_CLEANUP_ASSERT(m_semTerm.initialize());
+
+CLEANUP:
+       return res;
+}
+
+void CWorkerThread::finalRelease()
+{
+}
+
+SSMRESULT CWorkerThread::addTask(IThreadClient *pThreadClient, void *param)
+{
+       ClientEntry clientEntry;
+
+       pThreadClient->addRef();
+       clientEntry.pClient = pThreadClient;
+       clientEntry.pArg = param;
+
+       m_mtxClientEntry.lock();
+       if (m_ClientEntry.empty())
+       {
+               m_semTask.give();
+       }
+       m_ClientEntry.push_back(clientEntry);
+       //Let the task worker know, we just added task
+       m_mtxClientEntry.unlock();
+
+       return SSM_S_OK;
+}
+
+
+SSMRESULT CTasker::finalConstruct()
+{
+       SSMRESULT       res = SSM_E_FAIL;
+
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pThreadPool));
+
+       SSM_CLEANUP_ASSERT(m_pThreadPool->createWorkerThread(&m_pWorkerThread));
+
+CLEANUP:
+       return res;
+}
+
+void CTasker::finalRelease()
+{
+}
+
+SSMRESULT CTasker::addTask(IThreadClient *pThreadClient, void *param)
+{
+       return m_pWorkerThread->addTask(pThreadClient, param);
+}
+
+
+SSMRESULT CThreadPool::finalConstruct()
+{
+       return SSM_S_OK;
+}
+
+void CThreadPool::finalRelease()
+{
+       for (std::vector<IWorkerThread*>::iterator itor = m_lstWorkerThread.begin();
+               itor != m_lstWorkerThread.end(); ++itor)
+       {
+               (*itor)->release();
+       }
+}
+
+SSMRESULT CThreadPool::createWorkerThread(OUT IWorkerThread **ppWorkerThread)
+{
+       SSMRESULT res = SSM_E_FAIL;
+
+       IWorkerThread           *pWorkerThread = NULL;
+
+       SSM_CLEANUP_NULL_ASSERT(ppWorkerThread);
+       
+       SSM_CLEANUP_ASSERT(CreateInstance(OID_IWorkerThread, (IBase**)&pWorkerThread));
+       SSM_CLEANUP_ASSERT(pWorkerThread->initialize());
+       SSM_CLEANUP_ASSERT(pWorkerThread->queryInterface(OID_IWorkerThread, (IBase**)ppWorkerThread));
+       m_lstWorkerThread.push_back(pWorkerThread);
+
+CLEANUP:
+       return res;
+}
+
+SSMRESULT CThreadPool::destroyThreadPool()
+{
+       SSMRESULT       res = SSM_E_FAIL;
+
+       for (std::vector<IWorkerThread*>::iterator itor = m_lstWorkerThread.begin();
+               itor != m_lstWorkerThread.end(); ++itor)
+       {
+               SSM_CLEANUP_ASSERT((*itor)->terminate());
+       }
+
+       res = SSM_S_OK;
+
+CLEANUP:
+       return res;
+}
\ No newline at end of file
index 7c29676..710e43b 100644 (file)
@@ -179,7 +179,6 @@ private:
        T& t_;
 };
 
-#if defined(WIN32)
 /**
 * @class    CSimpleMutex
 * @brief    CSimpleMutex Interface
@@ -191,18 +190,19 @@ private:
 class CSimpleMutex
 {
 private:
+#if defined(WIN32)
        CRITICAL_SECTION m_criticalSection;
+#elif defined(LINUX)
+       pthread_mutex_t                 m_mutex;
+       pthread_mutexattr_t             m_mutexAttribute;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
 
 public:
-       CSimpleMutex()
-       {
-               InitializeCriticalSection(&m_criticalSection);
-       }
+       CSimpleMutex();
 
-       ~CSimpleMutex()
-       {
-               DeleteCriticalSection(&m_criticalSection);
-       }
+       ~CSimpleMutex();
 
        /**
        * @fn     lock
@@ -215,10 +215,7 @@ public:
        * @exception    
        * @see
        */
-       void lock()
-       {
-               EnterCriticalSection(&m_criticalSection);               
-       }
+       void lock();
 
        /**
        * @fn     unlock
@@ -231,181 +228,58 @@ public:
        * @exception    
        * @see
        */
-       void unlock()
-       {
-               LeaveCriticalSection(&m_criticalSection);
-       }
+       void unlock();
 };
 
-/**
-* @class    CTaskWorker
-* @brief    CTaskWorker Interface
-*                       This class represents worker thread utility that holds one thread
-*
-* @see
-*/
-class CTaskWorker
+class CSemaphore
 {
 private:
-       HANDLE m_hThread;
-
-       CSimpleMutex  m_mutex;
-
-       HANDLE m_hInitializeEvent;
-       HANDLE m_hAddTaskEvent;
-       HANDLE m_hShutdownEvent;
-       HANDLE m_hShutdownCompleteEvent;
-
-       struct ClientEntry
-       {
-               IThreadClient   *pClient;
-               void                    *pArg;
-       };
-
-       std::list<ClientEntry>  m_clientEntry;
-
-       static void _worker(void *pArg)
-       {
-               CTaskWorker *pThread = (CTaskWorker *)pArg;
-               return pThread->worker();
-       }
-
-       bool getTask(ClientEntry *clientEntry)
-       {               
-               HANDLE handles[] = {m_hShutdownEvent, m_hAddTaskEvent};
-
-               bool bRet = false;
+#if defined(WIN32)
+       HANDLE hSemaphore;
+#elif defined(LINUX)
+       sem_t hSemaphore;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
 
-               switch(WaitForMultipleObjects(2, handles, FALSE, INFINITE))
-               {
-                       //requested for shutdown
-               case WAIT_OBJECT_0:
-                       bRet = false;
-                       break;
+public:
+       CSemaphore();
 
-                       //requested for new task added
-               case WAIT_OBJECT_0 + 1:
-                       m_mutex.lock();
-                       *clientEntry = m_clientEntry.front();
-                       m_clientEntry.pop_front();
-                       if(m_clientEntry.empty())
-                       {
-                               ResetEvent(m_hAddTaskEvent);
-                       }
-                       m_mutex.unlock();
-                       bRet = true;
-                       break;
+       ~CSemaphore();
 
-                       //invalid event raised
-               default:
-                       bRet = false;
-                       break;
-               }
+       SSMRESULT initialize();
 
-               return bRet;
-       }
+       SSMRESULT destroy();
 
-       void worker()
-       {
-               ClientEntry clientEntry;
+       SSMRESULT take();
 
-               //Thread Creation completed
-               SetEvent(m_hInitializeEvent);
-
-               //Wait for any tasks
-               while(getTask(&clientEntry))
-               {
-                       clientEntry.pClient->onExecute(clientEntry.pArg);
-                       clientEntry.pClient->onTerminate(clientEntry.pArg);
-                       SAFE_RELEASE(clientEntry.pClient);
-               }
+       SSMRESULT give();
+};
 
-               //Thread is almost terminated
-               SetEvent(m_hShutdownCompleteEvent);
-       }
 
+static const OID OID_IWorkerThread = { 0x12a67457, 0xce97, 0x41c4, { 0x90, 0xb8, 0xcc, 0x72, 0x5f, 0xc4, 0x40, 0x27 } };
+/**
+* @class    IWorkerThread
+* @brief    IWorkerThread Interface
+*                       This class represents worker thread utility
+*
+* @see
+*/
+class IWorkerThread : public IBase
+{
 public:
-       CTaskWorker()
-       {
-               m_hThread = NULL;
-               m_hInitializeEvent = NULL;
-               m_hAddTaskEvent = NULL;
-               m_hShutdownEvent = NULL;
-               m_hShutdownCompleteEvent = NULL;
-       }
-
-       ~CTaskWorker()
-       {
-       }
-
        /**
        * @fn     initialize
        * @brief Initialize current worker thread
        *
        * @param NONE
-       * 
-       * @return SSMRESULT
-       * @warning      
-       * @exception    
-       * @see
-       */
-       SSMRESULT initialize()
-       {
-               m_hInitializeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-               m_hAddTaskEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
-               m_hShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-               m_hShutdownCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-               //Create thread and wait for jobs
-               m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_worker,
-                       this, 0, NULL);
-
-               if(m_hThread == NULL)
-               {
-                       return SSM_E_FAIL;
-               }
-
-               //Wait till thread creation is done
-               if(WaitForSingleObject(m_hInitializeEvent, INFINITE) != WAIT_OBJECT_0)
-               {
-                       return SSM_E_FAIL;
-               }
-
-               return SSM_S_OK;
-       }
-
-       /**
-       * @fn     addTask
-       * @brief Add task to current worker thread.\n
-       *                 Each task called only once
        *
-       * @param [in] IThreadClient *pThreadClient - Implemented thread client class instance that called from worker thread.
-       * @param [in] void *param - Optional parameter that IThreadClient::OnExecute/OnTerminate can receive
-       * 
        * @return SSMRESULT
-       * @warning      
-       * @exception    
+       * @warning
+       * @exception
        * @see
        */
-       SSMRESULT addTask(IThreadClient *pThreadClient, void *param)
-       {
-               ClientEntry clientEntry;
-
-               pThreadClient->addRef();
-               clientEntry.pClient = pThreadClient;
-               clientEntry.pArg = param;
-
-               m_mutex.lock();
-               m_clientEntry.push_back(clientEntry);
-               //Let the task worker know, we just added task
-               SetEvent(m_hAddTaskEvent);
-               m_mutex.unlock();
-
-               return SSM_S_OK;
-       }
+       virtual SSMRESULT initialize() = 0;
 
        /**
        * @fn     terminate
@@ -413,743 +287,93 @@ public:
        *                 All remained tasks are destroyed after IThreadClient::OnTerminate called
        *
        * @param NONE
-       * 
-       * @return SSMRESULT
-       * @warning      
-       * @exception    
-       * @see
-       */
-       SSMRESULT terminate()
-       {
-               SSMRESULT res = SSM_S_OK;
-               //Wait Created Thread's termination
-               SetEvent(m_hShutdownEvent);
-
-               //Wait till thread creation is done
-               if(WaitForSingleObject(m_hShutdownCompleteEvent, 10000) != WAIT_OBJECT_0)
-                       res = SSM_E_FAIL;
-
-               m_mutex.lock();
-               //Remove all tasks from queue
-               for(std::list<ClientEntry>::iterator itor = m_clientEntry.begin();
-                       itor != m_clientEntry.end(); ++itor)
-               {
-                       ClientEntry clientEntry = *itor;
-                       clientEntry.pClient->onTerminate(clientEntry.pArg);
-                       SAFE_RELEASE(clientEntry.pClient);
-               }
-               m_clientEntry.clear();
-               m_mutex.unlock();
-
-               if(m_hThread != NULL)
-               {
-                       CloseHandle(m_hThread);
-                       m_hThread = NULL;
-               }
-
-               if(m_hInitializeEvent != NULL)
-               {
-                       CloseHandle(m_hInitializeEvent);
-                       m_hInitializeEvent = NULL;
-               }
-
-               if(m_hAddTaskEvent != NULL)
-               {
-                       CloseHandle(m_hAddTaskEvent);
-                       m_hAddTaskEvent = NULL;
-               }
-
-               if(m_hShutdownEvent != NULL)
-               {
-                       CloseHandle(m_hShutdownEvent);
-                       m_hShutdownEvent = NULL;
-               }
-
-               if(m_hShutdownCompleteEvent != NULL)
-               {
-                       CloseHandle(m_hShutdownCompleteEvent);
-                       m_hShutdownCompleteEvent = NULL;
-               }
-
-               return res;
-       }
-};
-
-#else
-
-#define WFMO
-namespace neosmart
-{
-#ifdef WFMO
-       struct neosmart_wfmo_t_
-       {
-               pthread_mutex_t Mutex;
-               pthread_cond_t CVariable;
-               union
-               {
-                       int FiredEvent; //WFSO
-                       int EventsLeft; //WFMO
-               } Status;
-               bool StillWaiting;
-               int RefCount;
-               bool WaitAll;
-
-               void Destroy()
-               {
-                       pthread_mutex_destroy(&Mutex);
-                       pthread_cond_destroy(&CVariable);
-               }
-       };
-       typedef neosmart_wfmo_t_ *neosmart_wfmo_t;
-
-       struct neosmart_wfmo_info_t_
-       {
-               neosmart_wfmo_t Waiter;
-               int WaitIndex;
-       };
-       typedef neosmart_wfmo_info_t_ *neosmart_wfmo_info_t;
-#endif
-
-       struct neosmart_event_t_
-       {
-               bool AutoReset;
-               pthread_cond_t CVariable;
-               pthread_mutex_t Mutex;
-               bool State;
-#ifdef WFMO
-               std::deque<neosmart_wfmo_info_t_> RegisteredWaits;
-#endif
-       };
-       typedef neosmart_event_t_ * neosmart_event_t;
-
-#ifdef WFMO
-       static bool RemoveExpiredWaitHelper(neosmart_wfmo_info_t_ wait)
-       {
-               int result = pthread_mutex_trylock(&wait.Waiter->Mutex);
-
-               if(result == EBUSY)
-               {
-                       return false;
-               }
-
-               assert(result == 0);
-
-               if(wait.Waiter->StillWaiting == false)
-               {
-                       --wait.Waiter->RefCount;
-                       assert(wait.Waiter->RefCount >= 0);
-
-                       result = pthread_mutex_unlock(&wait.Waiter->Mutex);
-                       assert(result == 0);
-
-                       if(wait.Waiter->RefCount == 0)
-                       {
-                               wait.Waiter->Destroy();
-                               delete wait.Waiter;
-                       }
-                       else
-                       {
-                               ;/*NULL*/
-                       }
-
-                       return true;
-               }
-
-               result = pthread_mutex_unlock(&wait.Waiter->Mutex);
-               assert(result == 0);
-
-               return false;
-       }
-#endif
-
-       static int UnlockedWaitForEvent(neosmart_event_t event, uint64_t milliseconds)
-       {
-               int result = 0;
-               if(!event->State)
-               {
-                       //Zero-timeout event state check optimization
-                       if(milliseconds == 0)
-                       {
-                               return ETIMEDOUT;
-                       }
-
-                       timespec ts;
-                       if(milliseconds != (uint64_t) -1)
-                       {
-                               timeval tv;
-                               gettimeofday(&tv, NULL);
-
-                               uint64_t nanoseconds = ((uint64_t) tv.tv_sec) * 1000 * 1000 * 1000 + milliseconds * 1000 * 1000 + ((uint64_t) tv.tv_usec) * 1000;
-
-                               ts.tv_sec = nanoseconds / 1000 / 1000 / 1000;
-                               ts.tv_nsec = (nanoseconds - ((uint64_t) ts.tv_sec) * 1000 * 1000 * 1000);
-                       }
-
-                       do
-                       {
-                               //Regardless of whether it's an auto-reset or manual-reset event:
-                               //wait to obtain the event, then lock anyone else out
-                               if(milliseconds != (uint64_t) -1)
-                               {
-                                       result = pthread_cond_timedwait(&event->CVariable, &event->Mutex, &ts);
-                               }
-                               else
-                               {
-                                       result = pthread_cond_wait(&event->CVariable, &event->Mutex);
-                               }
-                       } while(result == 0 && !event->State);
-
-                       if(result == 0 && event->AutoReset)
-                       {
-                               //We've only accquired the event if the wait succeeded
-                               event->State = false;
-                       }
-               }
-               else if(event->AutoReset)
-               {
-                       //It's an auto-reset event that's currently available;
-                       //we need to stop anyone else from using it
-                       result = 0;
-                       event->State = false;
-               }
-               //Else we're trying to obtain a manual reset event with a signalled state;
-               //don't do anything
-               return result;
-       }
-
-       static int WaitForEvent(neosmart_event_t event, uint64_t milliseconds)
-       {
-               int tempResult;
-               if(milliseconds == 0)
-               {
-                       tempResult = pthread_mutex_trylock(&event->Mutex);
-                       if(tempResult == EBUSY)
-                       {
-                               return ETIMEDOUT;
-                       }
-               }
-               else
-               {
-                       tempResult = pthread_mutex_lock(&event->Mutex);
-               }
-
-               assert(tempResult == 0);
-
-               int result = UnlockedWaitForEvent(event, milliseconds);
-
-               tempResult = pthread_mutex_unlock(&event->Mutex);
-               assert(tempResult == 0);
-
-               return result;
-       }
-
-#ifdef WFMO
-       static int WaitForMultipleEvents(neosmart_event_t *events, int count, bool waitAll, uint64_t milliseconds, int &waitIndex)
-       {
-               neosmart_wfmo_t wfmo = new neosmart_wfmo_t_;
-
-               int result = 0;
-               int tempResult = pthread_mutex_init(&wfmo->Mutex, 0);
-               assert(tempResult == 0);
-
-               tempResult = pthread_cond_init(&wfmo->CVariable, 0);
-               assert(tempResult == 0);
-
-               neosmart_wfmo_info_t_ waitInfo;
-               waitInfo.Waiter = wfmo;
-               waitInfo.WaitIndex = -1;
-
-               wfmo->WaitAll = waitAll;
-               wfmo->StillWaiting = true;
-               wfmo->RefCount = 1;
-
-               if(waitAll)
-               {
-                       wfmo->Status.EventsLeft = count;
-               }
-               else
-               {
-                       wfmo->Status.FiredEvent = -1;
-               }
-
-               tempResult = pthread_mutex_lock(&wfmo->Mutex);
-               assert(tempResult == 0);
-
-               bool done = false;
-               waitIndex = -1;
-
-               for(int i = 0; i < count; ++i)
-               {
-                       waitInfo.WaitIndex = i;
-
-                       //Must not release lock until RegisteredWait is potentially added
-                       tempResult = pthread_mutex_lock(&events[i]->Mutex);
-                       assert(tempResult == 0);
-
-                       //Before adding this wait to the list of registered waits, let's clean up old, expired waits while we have the event lock anyway
-                       events[i]->RegisteredWaits.erase(std::remove_if(events[i]->RegisteredWaits.begin(), events[i]->RegisteredWaits.end(), RemoveExpiredWaitHelper), events[i]->RegisteredWaits.end());
-
-                       if(UnlockedWaitForEvent(events[i], 0) == 0)
-                       {
-                               tempResult = pthread_mutex_unlock(&events[i]->Mutex);
-                               assert(tempResult == 0);
-
-                               if(waitAll)
-                               {
-                                       --wfmo->Status.EventsLeft;
-                                       assert(wfmo->Status.EventsLeft >= 0);
-                               }
-                               else
-                               {
-                                       wfmo->Status.FiredEvent = i;
-                                       waitIndex = i;
-                                       done = true;
-                                       break;
-                               }
-                       }
-                       else
-                       {
-                               events[i]->RegisteredWaits.push_back(waitInfo);
-                               ++wfmo->RefCount;
-
-                               tempResult = pthread_mutex_unlock(&events[i]->Mutex);
-                               assert(tempResult == 0);
-                       }
-               }
-
-               timespec ts;
-               if(!done)
-               {
-                       if(milliseconds == 0)
-                       {
-                               result = ETIMEDOUT;
-                               done = true;
-                       }
-                       else if(milliseconds != (uint64_t) -1)
-                       {
-                               timeval tv;
-                               gettimeofday(&tv, NULL);
-
-                               uint64_t nanoseconds = ((uint64_t) tv.tv_sec) * 1000 * 1000 * 1000 + milliseconds * 1000 * 1000 + ((uint64_t) tv.tv_usec) * 1000;
-
-                               ts.tv_sec = nanoseconds / 1000 / 1000 / 1000;
-                               ts.tv_nsec = (nanoseconds - ((uint64_t) ts.tv_sec) * 1000 * 1000 * 1000);
-                       }
-               }
-
-               while(!done)
-               {
-                       //One (or more) of the events we're monitoring has been triggered?
-
-                       //If we're waiting for all events, assume we're done and check if there's an event that hasn't fired
-                       //But if we're waiting for just one event, assume we're not done until we find a fired event
-                       done = (waitAll && wfmo->Status.EventsLeft == 0) || (!waitAll && wfmo->Status.FiredEvent != -1);
-
-                       if(!done)
-                       {
-                               if(milliseconds != (uint64_t) -1)
-                               {
-                                       result = pthread_cond_timedwait(&wfmo->CVariable, &wfmo->Mutex, &ts);
-                               }
-                               else
-                               {
-                                       result = pthread_cond_wait(&wfmo->CVariable, &wfmo->Mutex);
-                               }
-
-                               if(result != 0)
-                               {
-                                       break;
-                               }
-                       }
-               }
-
-               waitIndex = wfmo->Status.FiredEvent;
-               wfmo->StillWaiting = false;
-
-               --wfmo->RefCount;
-               assert(wfmo->RefCount >= 0);
-
-               tempResult = pthread_mutex_unlock(&wfmo->Mutex);
-               assert(tempResult == 0);
-
-               if(wfmo->RefCount == 0)
-               {
-                       wfmo->Destroy();
-                       delete wfmo;
-               }
-               else
-               {
-                       ;/*NULL*/
-               }
-
-               return result;
-       }
-       /* //Unused
-       static int WaitForMultipleEvents(neosmart_event_t *events, int count, bool waitAll, uint64_t milliseconds)
-       {
-       int unused;
-       return WaitForMultipleEvents(events, count, waitAll, milliseconds, unused);
-       }
-       */
-#endif
-
-       static int DestroyEvent(neosmart_event_t event)
-       {
-               int result = pthread_cond_destroy(&event->CVariable);
-               assert(result == 0);
-
-               result = pthread_mutex_destroy(&event->Mutex);
-               assert(result == 0);
-
-               delete event;
-
-               return 0;
-       }
-
-       static int SetEvent(neosmart_event_t event)
-       {
-               int result = pthread_mutex_lock(&event->Mutex);
-               assert(result == 0);
-
-               event->State = true;
-
-               //Depending on the event type, we either trigger everyone or only one
-               if(event->AutoReset)
-               {
-#ifdef WFMO
-                       while(!event->RegisteredWaits.empty())
-                       {
-                               neosmart_wfmo_info_t i = &event->RegisteredWaits.front();
-
-                               result = pthread_mutex_lock(&i->Waiter->Mutex);
-                               assert(result == 0);
-
-                               --i->Waiter->RefCount;
-                               assert(i->Waiter->RefCount >= 0);
-                               if(!i->Waiter->StillWaiting)
-                               {
-                                       result = pthread_mutex_unlock(&i->Waiter->Mutex);
-                                       assert(result == 0);
-
-                                       if(i->Waiter->RefCount == 0)
-                                       {
-                                               i->Waiter->Destroy();
-                                               delete i->Waiter;
-                                       }
-                                       else
-                                       {
-                                               ;/*NULL*/
-                                       }
-                                       event->RegisteredWaits.pop_front();
-                                       continue;
-                               }
-
-                               event->State = false;
-
-                               if(i->Waiter->WaitAll)
-                               {
-                                       --i->Waiter->Status.EventsLeft;
-                                       assert(i->Waiter->Status.EventsLeft >= 0);
-                                       //We technically should do i->Waiter->StillWaiting = Waiter->Status.EventsLeft != 0
-                                       //but the only time it'll be equal to zero is if we're the last event, so no one
-                                       //else will be checking the StillWaiting flag. We're good to go without it.
-                               }
-                               else
-                               {
-                                       i->Waiter->Status.FiredEvent = i->WaitIndex;
-                                       i->Waiter->StillWaiting = false;
-                               }
-
-                               result = pthread_mutex_unlock(&i->Waiter->Mutex);
-                               assert(result == 0);
-
-                               result = pthread_cond_signal(&i->Waiter->CVariable);
-                               assert(result == 0);
-
-                               event->RegisteredWaits.pop_front();
-
-                               result = pthread_mutex_unlock(&event->Mutex);
-                               assert(result == 0);
-
-                               return 0;
-                       }
-#endif
-                       //event->State can be false if compiled with WFMO support
-                       if(event->State)
-                       {
-                               result = pthread_mutex_unlock(&event->Mutex);
-                               assert(result == 0);
-
-                               result = pthread_cond_signal(&event->CVariable);
-                               assert(result == 0);
-
-                               return 0;
-                       }
-               }
-               else
-               {
-#ifdef WFMO
-                       for(size_t i = 0; i < event->RegisteredWaits.size(); ++i)
-                       {
-                               neosmart_wfmo_info_t info = &event->RegisteredWaits[i];
-
-                               result = pthread_mutex_lock(&info->Waiter->Mutex);
-                               assert(result == 0);
-
-                               --info->Waiter->RefCount;
-                               assert(info->Waiter->RefCount >= 0);
-
-                               if(!info->Waiter->StillWaiting)
-                               {
-                                       result = pthread_mutex_unlock(&info->Waiter->Mutex);
-                                       assert(result == 0);
-
-                                       if(info->Waiter->RefCount == 0)
-                                       {
-                                               info->Waiter->Destroy();
-                                               delete info->Waiter;
-                                       }
-                                       else
-                                       {
-                                               ;/*NULL*/                                               
-                                       }
-                                       continue;
-                               }
-
-                               if(info->Waiter->WaitAll)
-                               {
-                                       --info->Waiter->Status.EventsLeft;
-                                       assert(info->Waiter->Status.EventsLeft >= 0);
-                                       //We technically should do i->Waiter->StillWaiting = Waiter->Status.EventsLeft != 0
-                                       //but the only time it'll be equal to zero is if we're the last event, so no one
-                                       //else will be checking the StillWaiting flag. We're good to go without it.
-                               }
-                               else
-                               {
-                                       info->Waiter->Status.FiredEvent = info->WaitIndex;
-                                       info->Waiter->StillWaiting = false;
-                               }
-
-                               result = pthread_mutex_unlock(&info->Waiter->Mutex);
-                               assert(result == 0);
-
-                               result = pthread_cond_signal(&info->Waiter->CVariable);
-                               assert(result == 0);
-                       }
-                       event->RegisteredWaits.clear();
-#endif
-                       result = pthread_mutex_unlock(&event->Mutex);
-                       assert(result == 0);
-
-                       result = pthread_cond_broadcast(&event->CVariable);
-                       assert(result == 0);
-               }
-
-               return 0;
-       }
-
-       static neosmart_event_t CreateEvent(bool manualReset, bool initialState)
-       {
-               neosmart_event_t event = new neosmart_event_t_;
-
-               int result = pthread_cond_init(&event->CVariable, 0);
-               assert(result == 0);
-
-               result = pthread_mutex_init(&event->Mutex, 0);
-               assert(result == 0);
-
-               event->State = false;
-               event->AutoReset = !manualReset;
-
-               if(initialState)
-               {
-                       result = SetEvent(event);
-                       assert(result == 0);
-               }
-
-               return event;
-       }
-       
-       static int ResetEvent(neosmart_event_t event)
-       {
-               int result = pthread_mutex_lock(&event->Mutex);
-               assert(result == 0);
-
-               event->State = false;
-
-               result = pthread_mutex_unlock(&event->Mutex);
-               assert(result == 0);
-
-               return 0;
-       }
-}
-
-/**
-* @class    CSimpleMutex
-* @brief    CSimpleMutex Interface
-*                       This class represents basic mutex class.\n
-*                       This mutex must support recursive locking mechanism
-*
-* @see
-*/
-class CSimpleMutex
-{
-private:
-       pthread_mutex_t                 m_mutex;
-       pthread_mutexattr_t             m_mutexAttribute;
-
-public:
-       CSimpleMutex()
-       {
-               pthread_mutexattr_init(&m_mutexAttribute);
-               pthread_mutexattr_settype(&m_mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
-               pthread_mutex_init(&m_mutex, &m_mutexAttribute);
-       }
-
-       ~CSimpleMutex()
-       {
-               pthread_mutex_destroy(&m_mutex);
-               pthread_mutexattr_destroy(&m_mutexAttribute);
-       }
-
-       /**
-       * @fn     lock
-       * @brief Lock current thread
        *
-       * @param NONE
-       * 
-       * @return NONE
-       * @warning      
-       * @exception    
+       * @return SSMRESULT
+       * @warning
+       * @exception
        * @see
        */
-       void lock()
-       {
-               pthread_mutex_lock( &m_mutex );
-       }
+       virtual SSMRESULT terminate() = 0;
 
        /**
-       * @fn     unlock
-       * @brief Unlock current thread
+       * @fn     addTask
+       * @brief Add task to current worker thread.\n
+       *                 Each task called only once
        *
-       * @param NONE
+       * @param [in] IThreadClient *pThreadClient - Implemented thread client class instance that called from worker thread.
+       * @param [in] void *param - Optional parameter that IThreadClient::OnExecute/OnTerminate can receive
        * 
-       * @return NONE
+       * @return SSMRESULT
        * @warning      
        * @exception    
        * @see
        */
-       void unlock()
-       {
-               pthread_mutex_unlock( &m_mutex );
-       }
+       virtual SSMRESULT addTask(IThreadClient *pThreadClient, void *param) = 0;
 };
 
 /**
-* @class    CTaskWorker
-* @brief    CTaskWorker Interface
+* @class    CWorkerThread
+* @brief    CWorkerThread Interface
 *                       This class represents worker thread utility that holds one thread
 *
 * @see
 */
-class CTaskWorker
+class CWorkerThread :
+       public CObjectRoot<CObjectMultiThreadModel>
+       , public IWorkerThread
 {
 private:
-       pthread_t m_hThread;
-
-       CSimpleMutex  m_mutex;
-
-       neosmart::neosmart_event_t m_hInitializeEvent;
-       neosmart::neosmart_event_t m_hAddTaskEvent;
-       neosmart::neosmart_event_t m_hShutdownEvent;
-       neosmart::neosmart_event_t m_hShutdownCompleteEvent;
-
        struct ClientEntry
        {
                IThreadClient   *pClient;
                void                    *pArg;
        };
+#if defined(WIN32)
+       HANDLE m_hThread;
+#elif defined(LINUX)
+       pthread_t m_hThread;
+#else
+#error WIN32 or LINUX tag must be defined
+#endif
+       CSemaphore                      m_semInit;
+       CSemaphore                      m_semTerm;
 
-       std::list<ClientEntry>  m_clientEntry;
-
-       static void _worker(void *pArg)
-       {
-               CTaskWorker *pThread = (CTaskWorker *)pArg;
-               return pThread->worker();
-       }
-
-       bool getTask(ClientEntry *clientEntry)
-       {
-               neosmart::neosmart_event_t handles[] = {m_hShutdownEvent, m_hAddTaskEvent};
-
-               bool bRet = false;
-               int index = 0;
+       CSimpleMutex                    m_mtxClientEntry;
+       CSimpleMutex                    m_mtxThreadTerm;        
+       CSemaphore                              m_semTask;
 
-               if(neosmart::WaitForMultipleEvents(handles, 2, false, -1, index) != 0)
-               {
-                       return false;
-               }
+       bool                                    m_bThreadTerm;
 
-               switch(index)
-               {
-                       //requested for shutdown
-               case 0:
-                       bRet = false;
-                       break;
+       std::list<ClientEntry>  m_ClientEntry;
 
-                       //requested for new task added
-               case 1:
-                       m_mutex.lock();
-                       *clientEntry = m_clientEntry.front();
-                       m_clientEntry.pop_front();
-                       if(m_clientEntry.empty())
-                       {
-                               neosmart::ResetEvent(m_hAddTaskEvent);
-                       }
-                       m_mutex.unlock();
-                       bRet = true;
-                       break;
+       bool getTask(ClientEntry *clientEntry);
 
-                       //invalid event raised
-               default:
-                       bRet = false;
-                       break;
-               }
+       void worker();
 
-               return bRet;
+       static void _worker(void *pArg)
+       {
+               CWorkerThread *pThread = (CWorkerThread *)pArg;
+               return pThread->worker();
        }
 
-       void worker()
-       {
-               ClientEntry clientEntry;
+public:
+       SSMRESULT finalConstruct();
+       void finalRelease();
 
-               //Thread Creation completed
-               neosmart::SetEvent(m_hInitializeEvent);
+       SSMRESULT queryInterface(const OID& objectID, IBase** ppObject)
+       {
+               if (ppObject == NULL)
+                       return SSM_E_POINTER;
 
-               //Wait for any tasks
-               while(getTask(&clientEntry))
+               if (IsEqualOID(objectID, OID_IWorkerThread))
                {
-                       clientEntry.pClient->onExecute(clientEntry.pArg);
-                       clientEntry.pClient->onTerminate(clientEntry.pArg);
-                       SAFE_RELEASE(clientEntry.pClient);
+                       IBase *pBase = (IWorkerThread*)this;
+                       pBase->addRef();
+                       *ppObject = pBase;
+                       return SSM_S_OK;
                }
 
-               //Thread is almost terminated
-               neosmart::SetEvent(m_hShutdownCompleteEvent);
-       }
-
-public:
-       CTaskWorker()
-       {
-               m_hThread = 0;
-               m_hInitializeEvent = NULL;
-               m_hAddTaskEvent = NULL;
-               m_hShutdownEvent = NULL;
-               m_hShutdownCompleteEvent = NULL;
-       }
-
-       ~CTaskWorker()
-       {
+               return SSM_E_NOINTERFACE;
        }
 
        /**
@@ -1157,36 +381,27 @@ public:
        * @brief Initialize current worker thread
        *
        * @param NONE
-       * 
+       *
        * @return SSMRESULT
-       * @warning      
-       * @exception    
+       * @warning
+       * @exception
        * @see
        */
-       SSMRESULT initialize()
-       {
-               m_hInitializeEvent = neosmart::CreateEvent(false, false);
-
-               m_hAddTaskEvent = neosmart::CreateEvent(true, false);
+       SSMRESULT initialize();
 
-               m_hShutdownEvent = neosmart::CreateEvent(false, false);
-
-               m_hShutdownCompleteEvent = neosmart::CreateEvent(false, false);
-
-               //Create thread and wait for jobs
-               if(pthread_create(&m_hThread, NULL, (void*(*)(void*))_worker, (void*)this) != 0)
-               {
-                       return SSM_E_FAIL;
-               }
-
-               //Wait till thread creation is done
-               if(neosmart::WaitForEvent(m_hInitializeEvent, -1) != 0)
-               {
-                       return SSM_E_FAIL;
-               }
-
-               return SSM_S_OK;
-       }
+       /**
+       * @fn     terminate
+       * @brief Terminate current worker thread.\n
+       *                 All remained tasks are destroyed after IThreadClient::OnTerminate called
+       *
+       * @param NONE
+       *
+       * @return SSMRESULT
+       * @warning
+       * @exception
+       * @see
+       */
+       SSMRESULT terminate();
 
        /**
        * @fn     addTask
@@ -1195,126 +410,29 @@ public:
        *
        * @param [in] IThreadClient *pThreadClient - Implemented thread client class instance that called from worker thread.
        * @param [in] void *param - Optional parameter that IThreadClient::OnExecute/OnTerminate can receive
-       * 
-       * @return SSMRESULT
-       * @warning      
-       * @exception    
-       * @see
-       */
-       SSMRESULT addTask(IThreadClient *pThreadClient, void *param)
-       {
-               ClientEntry clientEntry;
-
-               pThreadClient->addRef();
-               clientEntry.pClient = pThreadClient;
-               clientEntry.pArg = param;
-
-               m_mutex.lock();
-               m_clientEntry.push_back(clientEntry);
-               //Let the task worker know, we just added task
-               neosmart::SetEvent(m_hAddTaskEvent);
-               m_mutex.unlock();
-
-               return SSM_S_OK;
-       }
-
-       /**
-       * @fn     terminate
-       * @brief Terminate current worker thread.\n
-       *                 All remained tasks are destroyed after IThreadClient::OnTerminate called
        *
-       * @param NONE
-       * 
        * @return SSMRESULT
-       * @warning      
-       * @exception    
+       * @warning
+       * @exception
        * @see
        */
-       SSMRESULT terminate()
-       {
-               SSMRESULT res = SSM_S_OK;
-               //Wait Created Thread's termination
-               neosmart::SetEvent(m_hShutdownEvent);
-
-               //Wait till thread creation is done
-               if(neosmart::WaitForEvent(m_hShutdownCompleteEvent, 10000) != 0)
-               {
-                       res = SSM_E_FAIL;
-               }
-
-               m_mutex.lock();
-               //Remove all tasks from queue
-               for(std::list<ClientEntry>::iterator itor = m_clientEntry.begin();
-                       itor != m_clientEntry.end(); ++itor)
-               {
-                       ClientEntry clientEntry = *itor;
-                       clientEntry.pClient->onTerminate(clientEntry.pArg);
-                       SAFE_RELEASE(clientEntry.pClient);
-               }
-               m_clientEntry.clear();
-               m_mutex.unlock();
-
-               if(m_hThread != 0)
-               {
-                       pthread_detach(m_hThread);
-                       m_hThread = 0;
-               }
-
-               if(m_hInitializeEvent != NULL)
-               {
-                       neosmart::DestroyEvent(m_hInitializeEvent);
-                       m_hInitializeEvent = NULL;
-               }
-
-               if(m_hAddTaskEvent != NULL)
-               {
-                       neosmart::DestroyEvent(m_hAddTaskEvent);
-                       m_hAddTaskEvent = NULL;
-               }
-
-               if(m_hShutdownEvent != NULL)
-               {
-                       neosmart::DestroyEvent(m_hShutdownEvent);
-                       m_hShutdownEvent = NULL;
-               }
-
-               if(m_hShutdownCompleteEvent != NULL)
-               {
-                       neosmart::DestroyEvent(m_hShutdownCompleteEvent);
-                       m_hShutdownCompleteEvent = NULL;
-               }
-
-               return res;
-       }
+       SSMRESULT addTask(IThreadClient *pThreadClient, void *param);
 };
 
-#endif
 
 static const OID OID_IThreadPool = { 0x53855605, 0xb2a0, 0x4a31, { 0xa2, 0x60, 0x36, 0x4d, 0x43, 0xc1, 0x2f, 0x96 } };
 /**
 * @class    IThreadPool
 * @brief    IThreadPool Interface
-*                       This class represents worker thread pool utility
+*                       This class represents worker thread utility
 *
 * @see
 */
 class IThreadPool : public IBase
 {
 public:
-       /**
-       * @fn     addTask
-       * @brief Add task to current worker thread pool.\n
-       *                 Each task called only once
-       *
-       * @param [in] IThreadClient *pThreadClient - Implemented thread client class instance that called from worker thread.
-       * @param [in] void *param - Optional parameter that IThreadClient::OnExecute/OnTerminate can receive
-       * 
-       * @return SSMRESULT
-       * @warning      
-       * @exception    
-       * @see
-       */
-       virtual SSMRESULT addTask(IThreadClient *pThreadClient, void *param) = 0;
+       virtual SSMRESULT createWorkerThread(OUT IWorkerThread **ppWorkerThread) = 0;
+       virtual SSMRESULT destroyThreadPool() = 0;
 };
 
 /**
@@ -1329,18 +447,11 @@ class CThreadPool :
        , public IThreadPool
 {
 private:
-       CTaskWorker                     m_taskWorker;
+       std::vector<IWorkerThread*>     m_lstWorkerThread;
 
 public:
-       SSMRESULT finalConstruct()
-       {
-               return m_taskWorker.initialize();
-       }
-
-       void finalRelease()
-       {
-               m_taskWorker.terminate();
-       }
+       SSMRESULT finalConstruct();
+       void finalRelease();
 
        SSMRESULT queryInterface(const OID& objectID, IBase** ppObject)
        {
@@ -1358,23 +469,53 @@ public:
                return SSM_E_NOINTERFACE;
        }
 
-       /**
-       * @fn     addTask
-       * @brief Add task to current worker thread pool.\n
-       *                 Each task called only once
-       *
-       * @param [in] IThreadClient *pThreadClient - Implemented thread client class instance that called from worker thread.
-       * @param [in] void *param - Optional parameter that IThreadClient::OnExecute/OnTerminate can receive
-       * 
-       * @return SSMRESULT
-       * @warning      
-       * @exception    
-       * @see
-       */
-       SSMRESULT addTask(IThreadClient *pThreadClient, void *param)
+       SSMRESULT createWorkerThread(OUT IWorkerThread **ppWorkerThread);
+
+       SSMRESULT destroyThreadPool();
+};
+
+static const OID OID_ITasker = { 0x8f2b0b4f, 0xaab8, 0x4cbc, { 0x99, 0x1, 0x65, 0xde, 0x89, 0x82, 0x9f, 0x7a } };
+/**
+* @class    ITasker
+* @brief    ITasker Interface
+*                       This class represents worker thread utility
+*
+* @see
+*/
+class ITasker : public IBase
+{
+public:
+       virtual SSMRESULT addTask(IThreadClient *pThreadClient, void *param) = 0;
+};
+
+class CTasker :
+       public CObjectRoot<CObjectMultiThreadModel>
+       , public ITasker
+{
+private:
+       CObjectPtr<IThreadPool>         m_pThreadPool;
+       CObjectPtr<IWorkerThread>       m_pWorkerThread;
+
+public:
+       SSMRESULT finalConstruct();
+       void finalRelease();
+
+       SSMRESULT queryInterface(const OID& objectID, IBase** ppObject)
        {
-               return m_taskWorker.addTask(pThreadClient, param);
+               if (ppObject == NULL)
+                       return SSM_E_POINTER;
+
+               if (IsEqualOID(objectID, OID_ITasker))
+               {
+                       IBase *pBase = this;
+                       pBase->addRef();
+                       *ppObject = pBase;
+                       return SSM_S_OK;
+               }
+
+               return SSM_E_NOINTERFACE;
        }
-};
 
+       SSMRESULT addTask(IThreadClient *pThreadClient, void *param);
+};
 #endif
index d6939f6..1d45a9b 100644 (file)
@@ -23,7 +23,7 @@ SSMRESULT CConditionedQuery::finalConstruct()
 {
        SSMRESULT res = SSM_E_FAIL;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pTaskWorker));
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
        SSM_CLEANUP_ASSERT(CreateInstance(OID_IConditionedQueryResult, (IBase**)&m_pConditionedQueryResult));
 
        m_conditionedQueryEvent = NULL;
@@ -83,7 +83,7 @@ SSMRESULT CConditionedQuery::onConditionedModelTriggered(IN int triggerId)
        if(evaluatedConditions == 0)
        {
                m_pConditionedQueryResult->addRef();
-               SSM_CLEANUP_ASSERT(m_pTaskWorker->addTask(this, (IConditionedQueryResult*)m_pConditionedQueryResult));
+               SSM_CLEANUP_ASSERT(m_pTasker->addTask(this, (IConditionedQueryResult*)m_pConditionedQueryResult));
        }
 
        res = SSM_S_OK;
index c4dce3d..c85a086 100644 (file)
@@ -38,7 +38,7 @@ class CConditionedQuery :
        , public IConditionedModelEvent
 {
 private:
-       CObjectPtr<IThreadPool>                                 m_pTaskWorker;
+       CObjectPtr<ITasker>                                             m_pTasker;
        //CObjectPtr<IPropagationEngine>                        m_PropagationEngine;
        CObject<CConditionedQueryResult>                *m_pConditionedQueryResult;
        std::vector<IConditionedModel*>                 m_conditionedModels;
index 3db7601..1bb8eb1 100644 (file)
@@ -25,7 +25,7 @@ SSMRESULT CContextModel::finalConstruct()
        SSMRESULT res = SSM_E_FAIL;
        ModelProperty           defaultModelProperty;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pTaskWorker));
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
 
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IEvaluationEngine, (IBase**)&m_pEvaluationEngine));
 
@@ -102,7 +102,7 @@ void CContextModel::registerSSMResource(IN ActivationType activationType, IN int
                        pData = new int[2];
                        pData[0] = STATUS_ACTIVATE;
                        pData[1] = (int)pSSMResource;
-                       m_pTaskWorker->addTask(this, (void*)pData);
+                       m_pTasker->addTask(this, (void*)pData);
                        m_mapSubscribedDevice[targetDeviceDataId] = 1;
                }
                else
@@ -119,7 +119,7 @@ void CContextModel::registerSSMResource(IN ActivationType activationType, IN int
                                pData = new int[2];
                                pData[0] = STATUS_START_READ_VALUE;
                                pData[1] = (int)pSSMResource;
-                               m_pTaskWorker->addTask(this, (void*)pData);
+                               m_pTasker->addTask(this, (void*)pData);
                                m_mapGetDevice[targetDeviceDataId] = 1;
                        }
                        else
@@ -150,7 +150,7 @@ void CContextModel::unregisterSSMResource(IN ActivationType activationType, IN i
                                pData = new int[2];
                                pData[0] = STATUS_DEACTIVATE;
                                pData[1] = (int)pSSMResource;
-                               m_pTaskWorker->addTask(this, (void*)pData);
+                               m_pTasker->addTask(this, (void*)pData);
                                m_mapSubscribedDevice.erase(targetDeviceDataId);
                        }
                }
@@ -164,7 +164,7 @@ void CContextModel::unregisterSSMResource(IN ActivationType activationType, IN i
                                pData = new int[2];
                                pData[0] = STATUS_STOP_READ_VALUE;
                                pData[1] = (int)pSSMResource;
-                               m_pTaskWorker->addTask(this, (void*)pData);
+                               m_pTasker->addTask(this, (void*)pData);
                        }
                }
                break;
index 0c49780..2956213 100644 (file)
@@ -38,7 +38,7 @@ class CContextModel :
        , public IEvent
 {
 private:
-       CObjectPtr<IThreadPool>                                 m_pTaskWorker;
+       CObjectPtr<ITasker>                                             m_pTasker;
        CObjectPtr<IEvaluationEngine>                   m_pEvaluationEngine;
        CObjectPtr<IContextModel>                               m_pParentModel;
        ModelPropertyVec                                                m_modelProperties;
index ca93057..165c42e 100644 (file)
@@ -31,8 +31,7 @@ SSMRESULT CEvaluationEngine::finalConstruct()
        m_iTriggerId = 0;
        m_mtxTriggerId.unlock();
 
-       SSM_CLEANUP_ASSERT(m_taskWorker.initialize());
-
+       SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, (IBase**)&m_pTasker));
        SSM_CLEANUP_ASSERT(initializeEngine());
 
 CLEANUP:
@@ -42,8 +41,6 @@ CLEANUP:
 void CEvaluationEngine::finalRelease()
 {
        terminateEngine();
-
-       m_taskWorker.terminate();
 }
 
 SSMRESULT CEvaluationEngine::executeSQL_NoReturn(IN std::string strSQL)
@@ -108,7 +105,7 @@ SSMRESULT CEvaluationEngine::onWatcherTriggered(IN int triggerId, IN int dataId)
        int             *pData = new int[2];
        pData[0] = triggerId;
        pData[1] = dataId;
-       m_taskWorker.addTask(this, (void*)pData);
+       m_pTasker->addTask(this, (void*)pData);
        return SSM_S_OK;
 }
 
@@ -212,6 +209,8 @@ void CEvaluationEngine::terminateEngine()
 
        CHK_SQLITE(sqlite3_close(m_pSQLite3), SQLITE_OK);
 
+       m_pSQLite3 = NULL;
+
        res = SSM_S_OK;
 CLEANUP:
        return;
index 0ccb99f..768010a 100644 (file)
@@ -43,7 +43,7 @@ private:
        CSimpleMutex            m_mtxTriggerId;
        std::map<int, IEvaluationEngineEvent*>  m_mapTriggers;
        CSimpleMutex            m_mtxDataRelation;
-       CTaskWorker                     m_taskWorker;
+       CObjectPtr<ITasker>     m_pTasker;
 
        SSMRESULT executeSQL_NoReturn(IN std::string strSQL);
 
index 987a014..770a0ca 100644 (file)
@@ -24,7 +24,7 @@ SSMRESULT CPropagationEngine::finalConstruct()
 {
        SSMRESULT                               res = SSM_E_FAIL;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pTaskWorker));
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
 
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextDataReader, (IBase**)&m_pContextDataReader));
 
@@ -163,8 +163,7 @@ SSMRESULT CPropagationEngine::installContextModelFromISSMResource(IN ISSMResourc
        ModelProperty                           modelProperty;
        ModelPropertyVec                        modelProperties;
        CObject<CContextModel>          *pContextModel;
-       std::map<std::string, int>::iterator    itorSearchedDeviceId;
-       int                                                     deviceDataId = 0;
+       int                                                     deviceId = 0;
        std::string                                     lifeTime;
 
        switch((res = findContextModel(pSSMResource->type.c_str(), (IContextModel**)&pContextModel)))
@@ -226,21 +225,42 @@ SSMRESULT CPropagationEngine::installContextModelFromISSMResource(IN ISSMResourc
        }               
        
        //Update Device data to DB
-       modelProperty.propertyName = "fname"; 
+       SSM_CLEANUP_ASSERT(updateDeviceInfo(pSSMResource, &deviceId));
+
+       //TODO: Must be modified for restructuring
+       pContextModel->addSSMResourceAndDeviceDataId(pSSMResource->type, deviceId, pSSMResource);
+
+       res = SSM_S_OK;
+
+CLEANUP:
+       SAFE_RELEASE(pContextModel);
+       return res;
+}
+
+SSMRESULT CPropagationEngine::updateDeviceInfo(IN ISSMResource *pSSMResource, OUT int *deviceId)
+{
+       SSMRESULT res = SSM_E_FAIL;
+
+       ModelProperty                           modelProperty;
+       ModelPropertyVec                        modelProperties;
+       std::map<std::string, int>::iterator    itorSearchedDeviceId;
+       int                                                     deviceDataId;
+
+       modelProperty.propertyName = "fname";
        modelProperty.propertyType = ModelProperty::TYPE_TEXT;
        modelProperty.propertyValue = pSSMResource->friendlyName;
        modelProperties.push_back(modelProperty);
 
-       modelProperty.propertyName = "ip"; 
+       modelProperty.propertyName = "ip";
        modelProperty.propertyType = ModelProperty::TYPE_TEXT;
        modelProperty.propertyValue = pSSMResource->ip;
        modelProperties.push_back(modelProperty);
 
-       modelProperty.propertyName = "version"; 
+       modelProperty.propertyName = "version";
        modelProperty.propertyType = ModelProperty::TYPE_TEXT;
        modelProperty.propertyValue = "1.0";
        modelProperties.push_back(modelProperty);
-       
+
        itorSearchedDeviceId = m_searchedSensorDataId.find(pSSMResource->ip);
 
        if (itorSearchedDeviceId == m_searchedSensorDataId.end())
@@ -253,13 +273,12 @@ SSMRESULT CPropagationEngine::installContextModelFromISSMResource(IN ISSMResourc
                deviceDataId = m_searchedSensorDataId[pSSMResource->ip];
        }
 
-       //TODO: Must be modified for restructuring
-       pContextModel->addSSMResourceAndDeviceDataId(pSSMResource->type, deviceDataId, pSSMResource);
+       if (deviceId != NULL)
+               *deviceId = deviceDataId;
 
        res = SSM_S_OK;
 
 CLEANUP:
-       SAFE_RELEASE(pContextModel);
        return res;
 }
 
@@ -276,6 +295,8 @@ SSMRESULT CPropagationEngine::installResponseReactor(IN IResponseReactor *pRespo
                SSM_CLEANUP_ASSERT(installContextModelFromISSMResource(*itor));
        }
 
+       res = SSM_S_OK;
+
 CLEANUP:
        return res;
 }
@@ -306,39 +327,6 @@ CLEANUP:
        return res;
 }
 
-SSMRESULT CPropagationEngine::recoverEngineFromDatabase()
-{
-       SSMRESULT                               res = SSM_E_FAIL;
-       ModelConditionVec               deviceCondition(1);
-       IConditionedModel               *pDeviceInformation = NULL;
-       IntVec                                  sensorDataIds;
-       
-       deviceCondition[0].modelProperty.propertyName = "dataId";
-       deviceCondition[0].modelProperty.propertyValue = "1";
-       deviceCondition[0].modelProperty.propertyType = ModelProperty::TYPE_NUMERIC;
-       deviceCondition[0].predicate = ModelCondition::PREDICATE_EQ;
-       SSM_CLEANUP_ASSERT(m_pDeviceModel->createConditionedModel(&deviceCondition, &pDeviceInformation));
-       SSM_CLEANUP_ASSERT(pDeviceInformation->getAffectedData(&sensorDataIds));
-
-       if (sensorDataIds.size() > 0)
-       {
-               ModelPropertyVec                deviceModelValues;
-               SSM_CLEANUP_ASSERT(m_pDeviceModel->getModelData(sensorDataIds[0], &deviceModelValues));
-
-               for(unsigned int i=0; i < deviceModelValues.size(); i++)
-               {
-                       if(deviceModelValues[i].propertyName == "name")
-                       {
-                               m_searchedSensorDataId[deviceModelValues[i].propertyValue] = sensorDataIds[0];
-                       }
-               }
-       }
-
-CLEANUP:
-       SAFE_RELEASE(pDeviceInformation);
-       return res;
-}
-
 SSMRESULT CPropagationEngine::cleanUpRemoteDeviceInfo()
 {
        SSMRESULT                               res = SSM_E_FAIL;
@@ -409,7 +397,7 @@ int CPropagationEngine::onResourceEvent(IN RESOURCE_EVENT_TYPE eventType, IN ISS
 
        pMessage[0] = eventType;
        pMessage[1] = (int)pSSMResource;
-       return (int)m_pTaskWorker->addTask(this, (void*)pMessage);
+       return (int)m_pTasker->addTask(this, (void*)pMessage);
 }
 
 SSMRESULT CPropagationEngine::initializeEngine()
@@ -420,6 +408,8 @@ SSMRESULT CPropagationEngine::initializeEngine()
 
        ModelPropertyVec                deviceModelProperties(3);
 
+       ISSMResource                    ssmResource;
+
        SSM_CLEANUP_ASSERT(m_pEvaluationEngine->initializeEngine());
 
        //Create root model (Root)
@@ -443,7 +433,10 @@ SSMRESULT CPropagationEngine::initializeEngine()
        SSM_CLEANUP_ASSERT(installContextModel(m_pRootModel, IContextModel::CONSTRUCTION_TYPE_INTERNAL, "Device",
                &deviceModelProperties, &m_pDeviceModel));
 
-       SSM_CLEANUP_ASSERT(recoverEngineFromDatabase());
+       ssmResource.ip = "coap://127.0.0.1/";
+       ssmResource.friendlyName = "MyDevice";
+
+       SSM_CLEANUP_ASSERT(updateDeviceInfo(&ssmResource, NULL));
 
        SSM_CLEANUP_ASSERT(installResponseReactor(m_pResponseReactor));
 
index 48b3c1e..9a3fd14 100644 (file)
@@ -43,7 +43,7 @@ class CPropagationEngine :
        , public IResourceEvent
 {
 private:
-       CObjectPtr<IThreadPool>                                         m_pTaskWorker;
+       CObjectPtr<ITasker>                                                     m_pTasker;
        CObjectPtr<IEvaluationEngine>                           m_pEvaluationEngine;
        CObjectPtr<IContextModel>                                       m_pRootModel;
 
@@ -87,6 +87,8 @@ private:
 
        void terminateEngine();
 
+       SSMRESULT updateDeviceInfo(IN ISSMResource *pSSMResource, OUT int *deviceId);
+
 public:
        SSMRESULT finalConstruct();
 
index 2e5af43..fb1e1ef 100644 (file)
@@ -28,9 +28,9 @@ SSMRESULT CQueryEngine::finalConstruct()
 
        m_pQueryEngineEvent = NULL;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IPropagationEngine, (IBase**)&m_pPropagationEngine));
+       SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, (IBase**)&m_pTasker));
 
-       SSM_CLEANUP_ASSERT(m_taskWorker.initialize());
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IPropagationEngine, (IBase**)&m_pPropagationEngine));
 
 CLEANUP:
        return res;
@@ -40,8 +40,6 @@ void CQueryEngine::finalRelease()
 {
        m_pQueryEngineEvent = NULL;
 
-       m_taskWorker.terminate();
-
        m_mtxQueries.lock();
        
        for(std::map<int, IConditionedQuery*>::iterator itor = m_conditionedQueries.begin();
@@ -163,7 +161,7 @@ SSMRESULT CQueryEngine::processQueryResult(IN int userTriggerId, IN std::vector<
        pData[1] = userTriggerId;
        pData[2] = (int)pDataReader;
 
-       m_taskWorker.addTask(this, (void*)pData);
+       m_pTasker->addTask(this, (void*)pData);
 
        res = SSM_S_OK;
 
@@ -330,7 +328,7 @@ SSMRESULT CQueryEngine::executeContextQuery(IN std::string contextQuery, OUT int
                        pData[1] = m_cqid;
                        pData[2] = (int)pResult;
 
-                       m_taskWorker.addTask(this, (void*)pData);
+                       m_pTasker->addTask(this, (void*)pData);
                }
                else
                {
index 6115e58..31f4ed5 100644 (file)
@@ -49,7 +49,7 @@ private:
        int                                                                     m_cqid;
        IQueryEngineEvent                                       *m_pQueryEngineEvent;
        std::map<int, CContextQuery*>           m_contextQueries;
-       CTaskWorker                                                     m_taskWorker;
+       CObjectPtr<ITasker>                                     m_pTasker;
 
 private:
        SSMRESULT processQueryResult(IN int userTriggerId, IN std::vector<result_model> *result);
index 1dbb12d..c78c29b 100644 (file)
@@ -56,6 +56,8 @@ SSMRESULT CSoftSensorManager::initializeCore(IN std::string xmlDescription)
 
        std::string                                     name;
        std::string                                     type;
+       std::string                                     pathSoftSensors;
+       std::string                                     pathDescription;
 
        xmlDoc.parse<0>((char *)xmlDescription.c_str());
 
@@ -92,20 +94,35 @@ SSMRESULT CSoftSensorManager::initializeCore(IN std::string xmlDescription)
                                }
                        }
                }
+               else if (strKey == "Config")
+               {
+                       for (itemDevice = itemSSMCore->first_node(); itemDevice; itemDevice = itemDevice->next_sibling())
+                       {
+                               strKey = itemDevice->name();
+
+                               if (strKey == "SoftSensorRepository")
+                               {
+                                       pathSoftSensors = itemDevice->value();
+                               }
+                               else if (strKey == "SoftSensorDescription")
+                               {
+                                       pathDescription = itemDevice->value();
+                               }
+                               else
+                               {
+                                       ;/*NULL*/
+                               }
+                       }
+               }
                else
                {
                        ;/*NULL*/
                }
        }
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pThreadPool));
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextRepository, (IBase**)&m_pContextRepository));
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IResponseReactor, (IBase**)&m_pResponseReactor));
-       m_pContextRepository->setCurrentDeviceInfo(name, type);
-       
-       //SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ISharingLayer, (IBase**)&m_pSharingLayer));
-       //m_pSharingLayer->InitLayer(m_pLowLevelResponseReactor);
-       //m_pSharingLayer->SetLocalId(udn);
+       m_pContextRepository->setCurrentDeviceInfo(name, type, pathSoftSensors, pathDescription);
 
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IPropagationEngine, (IBase**)&m_pPropagationEngine));
 
@@ -163,6 +180,7 @@ SSMRESULT CSoftSensorManager::getInstalledModelList(OUT std::vector<ISSMResource
 
 CSimpleMutex                           *g_mtxGlobalInstance = NULL;
 std::map<OID, IBase*>          *g_globalInstance = NULL;
+IThreadPool                                    *g_pThreadPool = NULL;
 
 SSMRESULT CreateGlobalInstance(IN const OID& objectID, OUT IBase** ppvObject)
 {
@@ -177,7 +195,15 @@ SSMRESULT CreateGlobalInstance(IN const OID& objectID, OUT IBase** ppvObject)
 
        g_mtxGlobalInstance->lock();
        res = SSM_S_FALSE;
-       if(IsEqualOID(OID_IThreadPool, objectID))
+
+       if (IsEqualOID(OID_ITasker, objectID))
+       {
+               if (g_globalInstance->find(OID_ITasker) == g_globalInstance->end())
+               {
+                       SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, ppvObject));
+               }
+       }
+       else if(IsEqualOID(OID_IThreadPool, objectID))
        {
                if (g_globalInstance->find(OID_IThreadPool) == g_globalInstance->end())
                {
@@ -263,7 +289,15 @@ SSMRESULT CreateInstance(IN const OID& objectID, OUT IBase** ppObject)
 
        *ppObject = NULL;
 
-       if(IsEqualOID(OID_IThreadPool, objectID))
+       if (IsEqualOID(OID_ITasker, objectID))
+       {
+               SSM_CLEANUP_ASSERT(CreateNewObject<CTasker>(objectID, ppObject));
+       }
+       else if (IsEqualOID(OID_IWorkerThread, objectID))
+       {
+               SSM_CLEANUP_ASSERT(CreateNewObject<CWorkerThread>(objectID, ppObject));
+       }
+       else if(IsEqualOID(OID_IThreadPool, objectID))
        {
                SSM_CLEANUP_ASSERT(CreateNewObject<CThreadPool>(objectID, ppObject));
        }
@@ -342,8 +376,8 @@ SSMRESULT CreateGlobalInstanceRepo()
        SSM_CLEANUP_NULL_ASSERT(g_mtxGlobalInstance);
        g_globalInstance = new std::map<OID, IBase*>();
        SSM_CLEANUP_NULL_ASSERT(g_globalInstance);
-
-       res = SSM_S_OK;
+       
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&g_pThreadPool));
 
 CLEANUP:
        return res;
@@ -351,7 +385,14 @@ CLEANUP:
 
 SSMRESULT DestroyGlobalInstanceRepo()
 {
+       SSMRESULT res = SSM_E_FAIL;
+
+       SSM_CLEANUP_ASSERT(g_pThreadPool->destroyThreadPool());
+
+       SAFE_RELEASE(g_pThreadPool);
        SAFE_DELETE(g_mtxGlobalInstance);
        SAFE_DELETE(g_globalInstance);
-       return SSM_S_OK;
+       
+CLEANUP:
+       return res;
 }
index 58f922f..989bc4a 100644 (file)
@@ -44,7 +44,6 @@ class CSoftSensorManager :
 private:
        CObjectPtr<IContextRepository>          m_pContextRepository;
        CObjectPtr<IPropagationEngine>          m_pPropagationEngine;
-       CObjectPtr<IThreadPool>                         m_pThreadPool;
        CObjectPtr<IResponseReactor>            m_pResponseReactor;
 
 public:
index ab0202d..648be81 100644 (file)
@@ -25,7 +25,7 @@ SSMRESULT CContextExecutor::finalConstruct()
 
        ctxEvent = NULL;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pTaskWorker));
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextRepository, (IBase**)&m_pContextRepository));
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IContextDataReader, (IBase**)&m_pContextDataReader));
 
@@ -51,7 +51,7 @@ void CContextExecutor::addOutput(std::vector<ContextData> contextData)
 {
        //LOGE("ADDOUTPUT");
        std::map<std::string, CallbackData>::iterator   itor;
-       std::string type = contextData.at(0).rootName;
+       std::string type = contextData[0].rootName;
 
        //TODO: name must be a this soft sensors identifier
        //m_mtxRequestedContextCallback.Lock();
@@ -80,9 +80,9 @@ std::string CContextExecutor::checkError(std::vector<ContextData> data)
 
        for(unsigned int i = 0 ; i < data.size() ; ++i)
        {
-               if(data.at(i).outputProperty.at(0).find("error") != data.at(i).outputProperty.at(0).end())
+               if(data[i].outputProperty[0].find("error") != data[i].outputProperty[0].end())
                {
-                       errorMsg = data.at(i).outputProperty.at(0).find("error")->second ;
+                       errorMsg = data[i].outputProperty[0].find("error")->second ;
                        break;
                }
        }
@@ -102,7 +102,7 @@ void CContextExecutor::registerContext(TypeofEvent callType, ISSMResource *pSSMR
        m_requestedContextCallback[pSSMResource->type] = callbackData;
        //m_mtxRequestedContextCallback.Unlock();
 
-       //This is primitive sensor
+       //This is stand-alone sensor
        if (pSSMResource->inputList.size() == 0)
        {
                //Let sensors work
@@ -125,20 +125,20 @@ void CContextExecutor::registerContext(TypeofEvent callType, ISSMResource *pSSMR
 
        for (unsigned int i = 0; i < pSSMResource->inputList.size(); ++i)
        {
-               ISSMResource *pLowerResource = NULL;
-               if (findString(&baseList, pSSMResource->inputList.at(i), &pLowerResource) != SSM_E_FAIL) //if element of inputList is in the lower resources.
+               ISSMResource *pKeyResource = NULL;
+               if (findString(&baseList, pSSMResource->inputList[i], &pKeyResource) != SSM_E_FAIL) //if element of inputList is in the primitive resources.
                {
-                       if (m_relatedContextModel.find(pLowerResource->type) != m_relatedContextModel.end()) //already exists
+                       if (m_relatedSoftSensor.find(pKeyResource->type) != m_relatedSoftSensor.end()) //already exists
                        {
                                //EXIST!!!!
-                               //check related Context needs insert or not. if high resource is not a member of related context then insert.
-                               std::vector<std::string> highList = m_relatedContextModel[pLowerResource->type];
+                               //check related Context needs insert or not. if softSensor resource is not a member of related context then insert.
+                               std::vector<std::string> softSensorList = m_relatedSoftSensor[pKeyResource->type];
 
-                               for(unsigned int j = 0 ; j < highList.size() ; ++j)
+                               for (unsigned int j = 0; j < softSensorList.size(); ++j)
                                {
-                                       if (highList.at(j).compare(pSSMResource->type) != 0)
+                                       if (softSensorList[j].compare(pSSMResource->type) != 0)
                                        {
-                                               m_relatedContextModel[pLowerResource->type].push_back(pSSMResource->type);
+                                               m_relatedSoftSensor[pKeyResource->type].push_back(pSSMResource->type);
                                                break;
                                        }
                                }
@@ -147,15 +147,15 @@ void CContextExecutor::registerContext(TypeofEvent callType, ISSMResource *pSSMR
                        {
                                //NO EXIST!!!!
                                //insert resource in the all map and vector
-                               m_relatedContextModel[pLowerResource->type].push_back(pSSMResource->type);
+                               m_relatedSoftSensor[pKeyResource->type].push_back(pSSMResource->type);
 
                                //Recursive call
-                               registerContext(callType, pLowerResource, this);
+                               registerContext(callType, pKeyResource, this);
                        }
                }
                else //unable to find installed sensors. take it to keep list
                {
-                       m_mapResourceLookup[pSSMResource->inputList.at(i)].push_back(CallbackData(callType, pSSMResource->type, this));
+                       m_mapResourceLookup[pSSMResource->inputList[i]].push_back(CallbackData(callType, pSSMResource->type, this));
                }
        }
 }
@@ -179,9 +179,9 @@ void CContextExecutor::onExecute(IN void* pArg)
 
                        for (size_t i = 0; i < m_mapResourceLookup[pResource->type].size(); i++)
                        {
-                               callBack = &m_mapResourceLookup[pResource->type].at(i);
+                               callBack = &m_mapResourceLookup[pResource->type][i];
 
-                               m_relatedContextModel[pResource->type].push_back(callBack->m_name);
+                               m_relatedSoftSensor[pResource->type].push_back(callBack->m_name);
 
                                registerContext(callBack->m_callType, pResource, callBack->m_pCallbackEvent);
                        }
@@ -214,7 +214,7 @@ int CContextExecutor::onResourceEvent(RESOURCE_EVENT_TYPE eventType, ISSMResourc
 
        pMessage[0] = eventType;
        pMessage[1] = (int)pSSMResource;
-       return (int)m_pTaskWorker->addTask(this, (void*)pMessage);
+       return (int)m_pTasker->addTask(this, (void*)pMessage);
 }
 
 SSMRESULT CContextExecutor::findString(std::vector<ISSMResource*> *sList, const std::string str, ISSMResource **ppResource)
@@ -222,9 +222,9 @@ SSMRESULT CContextExecutor::findString(std::vector<ISSMResource*> *sList, const
        SSMRESULT ret = SSM_E_FAIL;
        for(unsigned int i = 0 ; i < sList->size() ; ++i)
        {
-               if(sList->at(i)->type == str)
+               if((*sList)[i]->type == str)
                {
-                       *ppResource = sList->at(i);
+                       *ppResource = (*sList)[i];
                        ret = SSM_S_OK;
                        break;
                }
@@ -232,43 +232,41 @@ SSMRESULT CContextExecutor::findString(std::vector<ISSMResource*> *sList, const
        return ret;
 }
 
-std::map<std::string, std::vector<ContextData> >  CContextExecutor::getPreparedContextList(std::string lowContextName)
+std::map<std::string, std::vector<ContextData> >  CContextExecutor::getPreparedContextList(std::string primitiveSensor)
 {
-       //check m_relatedContextModel / apply timestamp
-
-       std::vector<std::string> relatedHigherContextList = m_relatedContextModel[lowContextName];
+       //check m_relatedSoftSensor / apply timestamp
        std::map<std::string, std::vector<ContextData> > returnData;
 
        SSMRESULT ret = SSM_E_FAIL;
 
-       for (unsigned int i = 0; i < relatedHigherContextList.size(); ++i)
+       for (unsigned int i = 0; i < m_relatedSoftSensor[primitiveSensor].size(); ++i)
        {
-               std::string highContextName = relatedHigherContextList.at(i);
-               if (m_registeredResources.find(highContextName) != m_registeredResources.end())
+               std::string softSensorName = m_relatedSoftSensor[primitiveSensor][i];
+               if (m_registeredResources.find(softSensorName) != m_registeredResources.end())
                {
                        ret = SSM_S_OK;
-                       std::vector<std::string> inputList = m_registeredResources[highContextName]->inputList;
+                       std::vector<std::string> inputList = m_registeredResources[softSensorName]->inputList;
                        std::vector<ContextData> contextDataList;
                        for (unsigned int j = 0; j < inputList.size(); j++) //check all "inputlist" arrived or not
                        {
-                               if (m_storedLowerContextData.find(inputList.at(j)) == m_storedLowerContextData.end())
+                               if (m_storedPrimitiveSensorData.find(inputList[j]) == m_storedPrimitiveSensorData.end())
                                {
                                        ret = SSM_E_FAIL;
                                        break;
                                }
                                else
                                {
-                                       std::vector<ContextData> lowerData = m_storedLowerContextData[inputList.at(j)];
-                                       for (unsigned k = 0; k < lowerData.size(); k++)
+                                       std::vector<ContextData> primitiveSensorData = m_storedPrimitiveSensorData[inputList[j]];
+                                       for (unsigned k = 0; k < primitiveSensorData.size(); k++)
                                        {
-                                               contextDataList.push_back(lowerData.at(k));
+                                               contextDataList.push_back(primitiveSensorData[k]);
                                        }
                                }
                        }
 
                        if (ret == SSM_S_OK)
                        {
-                               returnData.insert(std::make_pair(highContextName, contextDataList));
+                               returnData.insert(std::make_pair(softSensorName, contextDataList));
                        }
                        contextDataList.clear();
                }
@@ -280,36 +278,34 @@ std::map<std::string, std::vector<ContextData> >  CContextExecutor::getPreparedC
 //Data from every primitive sensors
 int CContextExecutor::onEvent(std::string type, TypeofEvent callType, std::vector<ContextData> ctxData)
 {
-       //now getting data from low level 
-
        //std::string root_name = ctxData.at(0).root_name; //-> deviceId+ctxData.root_name
 
-       if (m_relatedContextModel.find(type) != m_relatedContextModel.end()) //already registered?
+       if (m_relatedSoftSensor.find(type) != m_relatedSoftSensor.end()) //already registered?
        {
                //update recent values(overwrite)               
-               m_storedLowerContextData[type] = ctxData;
+               m_storedPrimitiveSensorData[type] = ctxData;
 
-               //find high context model
+               //find soft sensor
                std::map<std::string, std::vector<ContextData> > readyContextList = getPreparedContextList(type);
 
                if (readyContextList.size() > 0)
                {
-                       //Run HighContext!  readyContextList has all data for run
+                       //Run SoftSensor!  readyContextList has all data for run
                        std::map<std::string, std::vector<ContextData> >::iterator iter = readyContextList.begin();
                        for (; iter != readyContextList.end(); ++iter)
                        {
-                               std::string highContextName = iter->first;
+                               std::string softSensorName = iter->first;
                                std::vector<ContextData> inputData = iter->second;
                                std::string errorMsg = checkError(inputData);
 
                                if (!errorMsg.compare("OK"))
                                {
-                                       runLogic(inputData, highContextName);
+                                       runLogic(inputData, softSensorName);
                                }
                                else
                                {
                                        inputData.clear();
-                                       inputData.push_back(makeErrorContextData(highContextName, errorMsg));
+                                       inputData.push_back(makeErrorContextData(softSensorName, errorMsg));
                                        addOutput(inputData);
                                }
                        }
@@ -339,11 +335,7 @@ void  CContextExecutor::unregisterContext(TypeofEvent callType, ISSMResource *pS
                        //TODO: Must free soft sensor
                        if (m_libraryList.find(pSSMResource->type) != m_libraryList.end() && callType != SSM_ONCE)
                        {
-#ifdef WIN32
-                               FreeLibrary((HINSTANCE)m_libraryList[pSSMResource->type]);
-#else
-                               dlclose(m_libraryList[pSSMResource->type]);
-#endif
+                               m_pContextRepository->unloadSoftSensor(m_libraryList[pSSMResource->type]);
                                m_libraryList.erase(m_libraryList.find(pSSMResource->type));
                        }
 
@@ -375,25 +367,24 @@ void  CContextExecutor::unregisterContext(TypeofEvent callType, ISSMResource *pS
        m_pContextRepository->getPrimitiveSensorList(&baseList);
        m_pContextRepository->getSoftSensorList(&baseList);
 
-
        for(unsigned int i = 0 ;i < pSSMResource->inputList.size() ; ++i)
        {
-               ISSMResource *pLowerResource = NULL;
-               if (findString(&baseList, pSSMResource->inputList.at(i), &pLowerResource) != SSM_E_FAIL)
+               ISSMResource *pPrimitiveSensor = NULL;
+               if (findString(&baseList, pSSMResource->inputList[i], &pPrimitiveSensor) != SSM_E_FAIL)
                {
-                       std::vector<std::string> *highList = &m_relatedContextModel[pLowerResource->type];
-                       for(unsigned int j = 0 ; j < highList->size() ; ++ j)
+                       std::vector<std::string> *softSensorList = &m_relatedSoftSensor[pPrimitiveSensor->type];
+                       for (unsigned int j = 0; j < softSensorList->size(); ++j)
                        {
-                               if (!highList->at(j).compare(pSSMResource->type))
+                               if (!(*softSensorList)[j].compare(pSSMResource->type))
                                {
-                                       highList->erase(highList->begin()+j);
+                                       softSensorList->erase(softSensorList->begin() + j);
 
-                                       if(highList->size() == 0) //if highList->size() == 0, then no more related context.
+                                       if (softSensorList->size() == 0) //no more related context.
                                        {
-                                               m_relatedContextModel.erase(m_relatedContextModel.find(pLowerResource->type));
+                                               m_relatedSoftSensor.erase(m_relatedSoftSensor.find(pPrimitiveSensor->type));
 
                                                //Recursive call
-                                               unregisterContext(callType, pLowerResource, this);
+                                               unregisterContext(callType, pPrimitiveSensor, this);
                                                break;
                                        }
                                }
@@ -403,20 +394,22 @@ void  CContextExecutor::unregisterContext(TypeofEvent callType, ISSMResource *pS
 }
 
 //Called when soft sensor try to work
-void CContextExecutor::runLogic(std::vector<ContextData> inputData,std::string highContextName )
+void CContextExecutor::runLogic(std::vector<ContextData> inputData, std::string softSensor)
 {      
        m_mtxLibraryIO.lock();
-       if(m_ctxEventList.find(highContextName) == m_ctxEventList.end())
-       {       
-               if (loadModelLibrary(highContextName) == SSM_S_OK)
+       if (m_ctxEventList.find(softSensor) == m_ctxEventList.end())
+       {
+               void *hSoftSensor = NULL;
+               if (m_pContextRepository->loadSoftSensor(softSensor, this, &hSoftSensor) == SSM_S_OK)
                {
-                       m_ctxEventList[highContextName] = ctxEvent;
-                       m_ctxEventList[highContextName]->onCtxEvent(SPF_START, inputData);
+                       m_libraryList[softSensor] = hSoftSensor;
+                       m_ctxEventList[softSensor] = ctxEvent;
+                       m_ctxEventList[softSensor]->onCtxEvent(SPF_START, inputData);
                }
        }
        else
        {
-               m_ctxEventList[highContextName]->onCtxEvent(SPF_START, inputData);
+               m_ctxEventList[softSensor]->onCtxEvent(SPF_START, inputData);
        }
        m_mtxLibraryIO.unlock();
 }
@@ -433,68 +426,4 @@ ContextData CContextExecutor::makeErrorContextData(std::string rootName, std::st
        errorContextData.outputProperty.push_back(errorMap);
                                        
        return errorContextData;
-}
-
-SSMRESULT CContextExecutor::loadModelLibrary(std::string modelName)
-{
-       std::stringstream       sstream;
-       SSMRESULT ret = SSM_E_FAIL;
-
-       typedef void (*InitContext)(IN ICtxDelegate *);
-       InitContext InitializeContextFunction = NULL;
-
-       // load dll(so)
-       for(unsigned int i = 1 ; i <= SSM_MODEL_RETRY; ++i)
-       {
-               sstream.str("");
-       
-#ifdef WIN32
-               sstream << MODEL_DIRECTORY << modelName.c_str() << ".dll" << std::ends;
-               
-               HINSTANCE m_hdll_MyModule = NULL;                       
-               m_hdll_MyModule = LoadLibraryA(sstream.str().c_str());
-
-               if(m_hdll_MyModule != NULL)
-               {
-                       InitializeContextFunction = (InitContext)GetProcAddress(m_hdll_MyModule, "InitializeContext");
-               }
-#else
-               //sstream << "/data/data/com.example.javaproject/lib/lib" << modelName <<".so" << std::ends;
-               sstream << MODEL_DIRECTORY << "lib" << modelName.c_str() <<".so" << std::ends;
-
-               void* m_hdll_MyModule = NULL;
-               m_hdll_MyModule = dlopen(sstream.str().c_str(), RTLD_LOCAL | RTLD_LAZY);
-
-               if(m_hdll_MyModule != NULL)
-               {
-                       InitializeContextFunction = (InitContext)dlsym(m_hdll_MyModule, "InitializeContext");
-               }
-#endif
-               if (m_hdll_MyModule == NULL)
-               {
-                       InitializeContextFunction = NULL;
-                       continue;
-               }
-
-               if (InitializeContextFunction != NULL)
-               {
-                       InitializeContextFunction(this);
-                       m_libraryList[modelName] = m_hdll_MyModule;
-                       ret = SSM_S_OK;
-               }
-               else
-               {
-#ifdef WIN32
-                       FreeLibrary((HINSTANCE)m_hdll_MyModule);
-#else
-                       dlclose(m_hdll_MyModule);
-#endif
-                       ret = SSM_E_FAIL;
-               }
-
-               break;
-       }
-
-       return ret;
-}
-
+}
\ No newline at end of file
index c2ef4df..5626442 100644 (file)
@@ -42,21 +42,21 @@ class CContextExecutor :
        , public IThreadClient
 {
 private:
-       CObjectPtr<IThreadPool>                 m_pTaskWorker;
+       CObjectPtr<ITasker>                             m_pTasker;
 
        CObjectPtr<IContextRepository>  m_pContextRepository;
 
        CObjectPtr<IContextDataReader>  m_pContextDataReader;
 
        /**
-       * @brief Context model data from lower layer
+       * @brief Sensor data from primitive sensors
        */
-       std::map<std::string, std::vector<ContextData> >                m_storedLowerContextData;
+       std::map<std::string, std::vector<ContextData> >                m_storedPrimitiveSensorData;
        
        /**
-       * @brief key = lower resource / values = high resources that has key(lower resource) in the input list
+       * @brief key = primitive, soft sensor / values = soft sensors that has key in the input list
        */
-       std::map<std::string, std::vector<std::string> >                m_relatedContextModel;
+       std::map<std::string, std::vector<std::string> >                m_relatedSoftSensor;
 
        /**
        * @brief requested high layer's callback data.(IEvent instance, deviceId, call type)
@@ -151,7 +151,7 @@ public:
        * @exception    
        * @see          
        */
-       void getDataFromDatabase(std::string modelName, int startIndex, int count, std::vector<ContextData> *data, int *pLastIndex);
+       void getDataFromDatabase(IN std::string modelName, IN int startIndex, IN int count, OUT std::vector<ContextData> *data, OUT int *pLastIndex);
        
        /**
        * @fn           onEvent
@@ -168,7 +168,7 @@ public:
        * @exception    
        * @see          
        */
-       int onEvent(IN std::string deviceID,IN TypeofEvent callType,IN std::vector<ContextData> ctxData);
+       int onEvent(IN std::string deviceID, IN TypeofEvent callType, IN std::vector<ContextData> ctxData);
        
        /**
        * @fn           registerContext
@@ -184,7 +184,7 @@ public:
        * @exception    
        * @see          
        */
-       void registerContext(IN TypeofEvent callType,IN ISSMResource *pSSMResouce,IN IEvent *pEvent);
+       void registerContext(IN TypeofEvent callType, IN ISSMResource *pSSMResouce, IN IEvent *pEvent);
 
        /**
        * @fn           unregisterContext
@@ -200,19 +200,18 @@ public:
        * @exception    
        * @see          
        */
-       void  unregisterContext(IN TypeofEvent callType, IN ISSMResource *pSSMResource,IN IEvent *pEvent);
+       void  unregisterContext(IN TypeofEvent callType, IN ISSMResource *pSSMResource, IN IEvent *pEvent);
 
        void onExecute(void* pArg);
        void onTerminate(void* pArg);
-       int onResourceEvent(RESOURCE_EVENT_TYPE eventType, ISSMResource *pSSMResource, std::string info);
+       int onResourceEvent(IN RESOURCE_EVENT_TYPE eventType, IN ISSMResource *pSSMResource, IN std::string info);
 
 private:
        SSMRESULT findString(IN std::vector<ISSMResource*> *sList, IN const std::string str, OUT ISSMResource **ppResource);
-       std::map<std::string,std::vector<ContextData> >  getPreparedContextList(IN std::string lowContextName);
-       void runLogic(IN std::vector<ContextData> inputData,IN  std::string highContextName);
+       std::map<std::string, std::vector<ContextData> >  getPreparedContextList(IN std::string primitiveSensor);
+       void runLogic(IN std::vector<ContextData> inputData, IN std::string softSensor);
        ContextData makeErrorContextData(IN std::string rootName, IN std::string errMsg);
-       SSMRESULT loadModelLibrary(IN std::string modelName);
-       std::string checkError(std::vector<ContextData> data);
+       std::string checkError(IN std::vector<ContextData> data);
 
 };
 
index fc269c0..e8a2fdf 100644 (file)
@@ -65,7 +65,7 @@ void CContextRepository::finalRelease()
 {
 }
 
-void CContextRepository::setCurrentDeviceInfo(IN std::string name, IN std::string type)
+void CContextRepository::setCurrentDeviceInfo(IN std::string name, IN std::string type, IN std::string pathSoftSensors, IN std::string pathDescription)
 {
        //TODO: Someone need to provides a way to generate permanent uuid function
        /*
@@ -79,11 +79,14 @@ void CContextRepository::setCurrentDeviceInfo(IN std::string name, IN std::strin
        */
        m_name = name;
        m_type = type;
+       m_pathSoftSensors = pathSoftSensors;
+       m_pathSoftSensorsDescription = pathDescription;
 }
 
-std::vector<DictionaryData> CContextRepository::loadXMLFromString(char *xmlData)
+SSMRESULT CContextRepository::loadXMLFromString(char *xmlData, std::vector<DictionaryData> *dataList)
 {
        // use  rapidxml-----------------------
+       SSMRESULT res = SSM_E_FAIL;
        rapidxml::xml_document< char > xmlDoc;
        //xmlDoc.parse< 0 >( &xmlData.front() );
        xmlDoc.parse< 0 >(xmlData);
@@ -96,14 +99,12 @@ std::vector<DictionaryData> CContextRepository::loadXMLFromString(char *xmlData)
        rapidxml::xml_node< char > *subItem2;
        rapidxml::xml_node< char > *subItem3;
 
-       std::vector<DictionaryData> dictionaryDataList;
        // get value
        rapidxml::xml_node< char > *root = xmlDoc.first_node();
 
-       //SSM_RESULT_ASSERT(root,"XML file is empty",dictionaryDataList);
        if(!root)
        {
-               return dictionaryDataList;
+               SSM_CLEANUP_ASSERT(SSM_E_FAIL);
        }
 
        for( item = root->first_node(); item; item = item->next_sibling() )
@@ -190,50 +191,78 @@ std::vector<DictionaryData> CContextRepository::loadXMLFromString(char *xmlData)
                dictionaryData.output_property_count = std::to_string((long long)dictionaryData.output_property.size());
                */
 
-               dictionaryDataList.push_back(dictionaryData);
+               dataList->push_back(dictionaryData);
        }
 
-       return dictionaryDataList;
+       res = SSM_S_OK;
+
+CLEANUP:
+       return res;
 }
 
-std::vector<DictionaryData> CContextRepository::loadXMLFromFile(const char *strFile )
+SSMRESULT CContextRepository::loadXMLFromFile(std::string descriptionFilePath, std::vector<DictionaryData> *dataList)
 {
-       std::basic_ifstream< char > xmlFile( strFile );
-       std::vector<DictionaryData> returnData;
+       SSMRESULT res = SSM_E_FAIL;
+       std::basic_ifstream< char > xmlFile(descriptionFilePath.c_str());
 
-       //SSM_RESULT_ASSERT(!xmlFile.fail(),"File open failed.",returnData);
-       
-       if(!xmlFile.fail())
+       if (descriptionFilePath.length() > 0 && xmlFile.fail())
+       {
+               //error while opening given path, return error
+               SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+       }
+
+       if (descriptionFilePath.length() == 0)
+       {
+               //No given path, try to open local Path
+               std::string path;
+               SSM_CLEANUP_ASSERT(GetCurrentPath(&path));
+               path.append("/");
+               path.append(DEFAULT_PATH_SOFT_SENSORS);
+               xmlFile.open(path);
+       }
+
+       //path loaded
+       if (!xmlFile.fail())
        {
                xmlFile.seekg(0, std::ios::end);
                unsigned int size = (unsigned int)xmlFile.tellg();
                xmlFile.seekg(0);
 
-               std::vector< char > xmlData(size+1);
+               std::vector< char > xmlData(size + 1);
                xmlData[size] = 0;
 
-               xmlFile.read( &xmlData.front(), (std::streamsize)size );
+               xmlFile.read(&xmlData.front(), (std::streamsize)size);
                xmlFile.close();
-               returnData = loadXMLFromString(&xmlData.front());
+               SSM_CLEANUP_ASSERT(loadXMLFromString(&xmlData.front(), dataList));
+       }
+       else
+       {
+               //let work with no soft sensor manager
+               res = SSM_S_OK;
        }
 
-       return returnData;
+CLEANUP:
+       return res;
 }
 
-SSMRESULT CContextRepository::getSoftSensorList(OUT std::vector<ISSMResource*> *pHighLevelList)
+SSMRESULT CContextRepository::getSoftSensorList(OUT std::vector<ISSMResource*> *pSoftSensorList)
 {
        SSMRESULT res = SSM_E_FAIL;
-       std::vector<DictionaryData> dict = loadXMLFromFile(HIGH_LOCATION);
-       res = makeSSMResourceListForDictionaryData("HIGH", dict, pHighLevelList);
+       std::vector<DictionaryData> dict;
+       
+       SSM_CLEANUP_ASSERT(loadXMLFromFile(m_pathSoftSensorsDescription.c_str(), &dict));
+
+       SSM_CLEANUP_ASSERT(makeSSMResourceListForDictionaryData(dict, pSoftSensorList));
 
+CLEANUP:
        return res;
 }
 
-SSMRESULT CContextRepository::getPrimitiveSensorList(OUT std::vector<ISSMResource*> *pLowLevelList)
+SSMRESULT CContextRepository::getPrimitiveSensorList(OUT std::vector<ISSMResource*> *pPrimitiveSensorList)
 {
        for (size_t i = 0; i < m_lstSensor.size(); i++)
        {
-               pLowLevelList->push_back(m_lstSensor.at(i));
+               pPrimitiveSensorList->push_back(m_lstSensor.at(i));
        }
 
        return SSM_S_OK;
@@ -276,7 +305,7 @@ SSMRESULT CContextRepository::stopObserveResource(IN ISSMResource *pSensor)
 }
 
 //TODO: Need to fix
-SSMRESULT CContextRepository::makeSSMResourceListForDictionaryData(const std::string typeString, std::vector<DictionaryData> dataList, std::vector<ISSMResource*> *pList)
+SSMRESULT CContextRepository::makeSSMResourceListForDictionaryData(std::vector<DictionaryData> dataList, std::vector<ISSMResource*> *pList)
 {
        SSMRESULT res = SSM_E_FAIL;
 
@@ -284,19 +313,19 @@ SSMRESULT CContextRepository::makeSSMResourceListForDictionaryData(const std::st
        {
                ISSMResource *pResource = new ISSMResource();
                pResource->location = SENSOR_LOCATION_LOCAL;
-               pResource->type = dataList.at(i).rootName;
-               pResource->name = std::string("coap://127.0.0.1/") + dataList.at(i).rootName;
+               pResource->type = dataList[i].rootName;
+               pResource->name = std::string("coap://127.0.0.1/") + dataList[i].rootName;
                pResource->ip = "coap://127.0.0.1/";
 
-               pResource->inputList = dataList.at(i).inputs;
+               pResource->inputList = dataList[i].inputs;
                
-               for(unsigned int j = 0 ; j <  dataList.at(i).outputProperty.size() ;++j )
+               for (unsigned int j = 0; j < dataList[i].outputProperty.size(); ++j)
                {
-                       pResource->outputProperty.push_back(dataList.at(i).outputProperty.at(j));
+                       pResource->outputProperty.push_back(dataList[i].outputProperty[j]);
                }
-               for(unsigned int j = 0 ; j <  dataList.at(i).attributeProperty.size() ;++j )
+               for (unsigned int j = 0; j < dataList[i].attributeProperty.size(); ++j)
                {
-                       pResource->outputProperty.push_back(dataList.at(i).attributeProperty.at(j));
+                       pResource->outputProperty.push_back(dataList[i].attributeProperty[j]);
                }
                pList->push_back(pResource);
        }
@@ -305,3 +334,132 @@ SSMRESULT CContextRepository::makeSSMResourceListForDictionaryData(const std::st
 
        return res;
 }
+
+SSMRESULT CContextRepository::loadSoftSensor(std::string softSensorName, ICtxDelegate *pDelegate, void **hSoftSensor)
+{
+       std::stringstream       sstream;
+       SSMRESULT                       res = SSM_E_FAIL;
+
+       typedef void(*InitContext)(IN ICtxDelegate *);
+       InitContext InitializeContextFunction = NULL;
+
+       if (m_pathSoftSensors.length() == 0)
+       {
+               SSM_CLEANUP_ASSERT(GetCurrentPath(&m_pathSoftSensors));
+       }
+
+       m_pathSoftSensors.append("/");
+
+       // load dll(so)
+       res = SSM_E_FAIL;
+       for (unsigned int i = 1; i <= SSM_MODEL_RETRY; ++i)
+       {
+               sstream.str("");
+
+#ifdef WIN32
+               sstream << m_pathSoftSensors << softSensorName.c_str() << ".dll" << std::ends;
+
+               HINSTANCE hModule = NULL;
+               hModule = LoadLibraryA(sstream.str().c_str());
+
+               if (hModule != NULL)
+               {
+                       InitializeContextFunction = (InitContext)GetProcAddress(hModule, "InitializeContext");
+               }
+#else
+               //sstream << "/data/data/com.example.javaproject/lib/lib" << modelName <<".so" << std::ends;
+               sstream << m_pathSoftSensors << "lib" << softSensorName.c_str() << ".so" << std::ends;
+
+               void* hModule = NULL;
+               hModule = dlopen(sstream.str().c_str(), RTLD_LOCAL | RTLD_LAZY);
+
+               if (hModule != NULL)
+               {
+                       InitializeContextFunction = (InitContext)dlsym(hModule, "InitializeContext");
+               }
+#endif
+               if (hModule == NULL)
+               {
+                       InitializeContextFunction = NULL;
+                       continue;
+               }
+
+               if (InitializeContextFunction != NULL)
+               {
+                       InitializeContextFunction(pDelegate);
+                       *hSoftSensor = hModule;
+                       res = SSM_S_OK;
+               }
+               else
+               {
+                       //Unload module and return error
+                       SSM_CLEANUP_ASSERT(unloadSoftSensor(hModule));
+                       SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+               }
+
+               break;
+       }
+
+CLEANUP:
+       return res;
+}
+
+SSMRESULT CContextRepository::unloadSoftSensor(void *hSoftSensor)
+{
+       SSMRESULT                       res = SSM_E_FAIL;
+
+#ifdef WIN32
+       SSM_CLEANUP_COND_ASSERT(FreeLibrary((HINSTANCE)hSoftSensor), TRUE, "FreeLibrary failed");
+#else
+       SSM_CLEANUP_COND_ASSERT(dlclose(hSoftSensor), 0, "dlclose failed");
+#endif
+
+       res = SSM_S_OK;
+
+CLEANUP:
+       return res;
+}
+
+SSMRESULT CContextRepository::GetCurrentPath(std::string *path)
+{
+       char            buffer[2048];
+       SSMRESULT       res = SSM_E_FAIL;
+#if defined(WIN32)
+       DWORD length = GetModuleFileNameA(NULL, buffer, 2047);
+
+       if (length == 0)
+       {
+               SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+       }
+
+       buffer[length] = '\0';
+       if (PathRemoveFileSpecA(buffer) == 0)
+       {
+               SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+       }
+
+#elif defined(LINUX)
+       char    *strPath = NULL;
+       int length = ::readlink("/proc/self/exe", buffer, 2047);
+
+       if (length == -1)
+       {
+               SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+       }
+
+       strPath = strrchr(buffer, '/');
+
+       if (strPath == NULL)
+       {
+               SSM_CLEANUP_ASSERT(SSM_E_FAIL);
+       }
+
+       *strPath = '\0';
+#endif
+
+       path->append(buffer);
+       res = SSM_S_OK;
+
+CLEANUP:
+       return res;
+}
\ No newline at end of file
index cb863fc..f1e9aa1 100644 (file)
@@ -47,6 +47,8 @@ private:
    std::string                                 m_name;
    std::string                                 m_type;
    std::vector<IResourceEvent*>        m_resourceEvents;
+   std::string                                 m_pathSoftSensors;
+   std::string                                 m_pathSoftSensorsDescription;
 
 public:
        SSMRESULT finalConstruct();
@@ -75,19 +77,21 @@ public:
        *
        * @param        [in] std::string name - Device name
        * @param        [in] std::string type - Device Type
+       * @param        [in] std::string pathSoftSensors - SoftSensors Repository path
+       * @param        [in] std::string pathDescription - SoftSensors Description path
        * @return       void
        *
        * @warning      
        * @exception    
        * @see          
        */
-       void setCurrentDeviceInfo(IN std::string name, IN std::string type);
+       void setCurrentDeviceInfo(IN std::string name, IN std::string type, IN std::string pathSoftSensors, IN std::string pathDescription);
        
        /**
        * @fn           getSoftSensorList
-       * @brief        Get high level context resource list
+       * @brief        Get soft sensor list
        *
-       * @param                [out] std::vector<ISSMResource*> *pSoftSensorList - High level context list
+       * @param                [out] std::vector<ISSMResource*> *pSoftSensorList - List of soft sensors
        * @return       SSMRESULT
        *                                       SSM_S_OK
        *                                       , SSM_S_FALSE
@@ -105,9 +109,9 @@ public:
 
        /**
        * @fn           getPrimitiveSensorList
-       * @brief        Get low level context resource list
+       * @brief        Get primitive sensor list
        *
-       * @param                [out] std::vector<ISSMResource*> *pPrimitiveSensorList - Low level context list
+       * @param                [out] std::vector<ISSMResource*> *pPrimitiveSensorList - List of primitive sensors
        * @return       SSMRESULT
        *                                       SSM_S_OK
        *                                       , SSM_S_FALSE
@@ -131,9 +135,13 @@ public:
        SSMRESULT startObserveResource(IN ISSMResource *pSensor, IN IEvent *pEvent);
        SSMRESULT stopObserveResource(IN ISSMResource *pSensor);
 
+       SSMRESULT loadSoftSensor(IN std::string softSensorName, IN ICtxDelegate *pDelegate, OUT void **hSoftSensor);
+       SSMRESULT unloadSoftSensor(IN void *hSoftSensor);
+
 private:
-       SSMRESULT makeSSMResourceListForDictionaryData(IN const std::string typeString, IN std::vector<DictionaryData> dataList, OUT std::vector<ISSMResource*> *pList) ;
-       std::vector<DictionaryData> loadXMLFromString(IN char *xmlData);
-       std::vector<DictionaryData> loadXMLFromFile(IN const char *strFile );
+       SSMRESULT makeSSMResourceListForDictionaryData(IN std::vector<DictionaryData> dataList, OUT std::vector<ISSMResource*> *pList) ;
+       SSMRESULT loadXMLFromFile(IN std::string descriptionFilePath, IN std::vector<DictionaryData> *dataList);
+       SSMRESULT loadXMLFromString(IN char *xmlData, IN std::vector<DictionaryData> *dataList);
+       SSMRESULT GetCurrentPath(OUT std::string *path);
 };
 #endif
\ No newline at end of file
index 0206bd8..278937e 100644 (file)
@@ -23,7 +23,7 @@ SSMRESULT CResourceFinder::finalConstruct()
 {
        SSMRESULT res = SSM_E_FAIL;
 
-       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pTaskWorker));
+       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
        SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IResourceConnectivity, (IBase**)&m_pResourceConnectivity));
 
        m_pResourceFinderEvent = NULL;
@@ -51,7 +51,7 @@ void CResourceFinder::onResourceFound(std::shared_ptr<OC::OCResource> resource)
                pMessage[0] = RESOURCE_DISCOVER_REQUESTPROFILE;
                pMessage[1] = (int)new std::shared_ptr<OC::OCResource>(resource);
 
-               m_pTaskWorker->addTask(this, pMessage);
+               m_pTasker->addTask(this, pMessage);
        }
 }
 
index af8550b..6638ca3 100644 (file)
@@ -74,7 +74,7 @@ private:
                {
                        SSMRESULT       res = SSM_E_FAIL;
 
-                       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase**)&m_pTaskWorker));
+                       SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase**)&m_pTasker));
                        m_pResource = resource;
                        m_pResourceFinderClient = pThreadClient;
 
@@ -172,11 +172,11 @@ private:
                        pMessage[0] = RESOURCE_DISCOVER_SETUP_RESOURCE;
                        pMessage[1] = (int)pSSMResource;
 
-                       m_pTaskWorker->addTask(m_pResourceFinderClient, (void*)pMessage);
+                       m_pTasker->addTask(m_pResourceFinderClient, (void*)pMessage);
                }
 
        private:
-               CObjectPtr<IThreadPool>                         m_pTaskWorker;
+               CObjectPtr<ITasker>                                     m_pTasker;
                std::shared_ptr<OC::OCResource>         m_pResource;
                IThreadClient                                           *m_pResourceFinderClient;
                IEvent                                                          *m_pEvent;
@@ -186,7 +186,7 @@ private:
        OC::OCPlatform                                          *m_pPlatform;
        CObjectPtr<IResourceConnectivity>       m_pResourceConnectivity;
        IResourceFinderEvent                            *m_pResourceFinderEvent;
-       CObjectPtr<IThreadPool>                         m_pTaskWorker;
+       CObjectPtr<ITasker>                             m_pTasker;
        std::map<std::string , OICResourceHandler*>     m_mapResourceHandler;
 };