From: jk13 Date: Mon, 17 Nov 2014 11:11:03 +0000 (+0900) Subject: [SSM] Modify thread util and framework init method X-Git-Tag: 1.2.0+RC1~2095^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=788263307bd2dc504426e4cb1a45e4d23f90956a;p=platform%2Fupstream%2Fiotivity.git [SSM] Modify thread util and framework init method 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. abcde123-31f8-11b4-a222-08002b34c003 MyPC PC /usr/local/SSRepo/ /usr/local/SSRepo/SSDescription.xml Change-Id: Id2c0746357d9e850e9e90016547b116412b758d2 Signed-off-by: Kim Jee Hyeok --- diff --git a/service/soft-sensor-manager/SSMCore/src/Common/InternalInterface.h b/service/soft-sensor-manager/SSMCore/src/Common/InternalInterface.h index 774a74e..6da528e 100644 --- a/service/soft-sensor-manager/SSMCore/src/Common/InternalInterface.h +++ b/service/soft-sensor-manager/SSMCore/src/Common/InternalInterface.h @@ -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 diff --git a/service/soft-sensor-manager/SSMCore/src/Common/PlatformLayer.h b/service/soft-sensor-manager/SSMCore/src/Common/PlatformLayer.h index 514351c..a102ee7 100644 --- a/service/soft-sensor-manager/SSMCore/src/Common/PlatformLayer.h +++ b/service/soft-sensor-manager/SSMCore/src/Common/PlatformLayer.h @@ -20,6 +20,9 @@ #if defined(WIN32) #include +#include + +#pragma comment(lib, "Shlwapi.lib") #pragma comment(lib, "../Outputs/sqlite3.lib") #elif defined(LINUX) @@ -28,6 +31,7 @@ #include #include #include +#include #elif defined(ANDROID) #include @@ -37,57 +41,14 @@ #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) \ { \ @@ -143,10 +104,6 @@ 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 index 0000000..8ab9b07 --- /dev/null +++ b/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.cpp @@ -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::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::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::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 diff --git a/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.h b/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.h index 7c29676..710e43b 100644 --- a/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.h +++ b/service/soft-sensor-manager/SSMCore/src/Common/ThreadManager.h @@ -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 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::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 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 + , 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 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 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::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 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 + , public ITasker +{ +private: + CObjectPtr m_pThreadPool; + CObjectPtr 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 diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.cpp b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.cpp index d6939f6..1d45a9b 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.cpp +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.cpp @@ -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; diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.h b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.h index c4dce3d..c85a086 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.h +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ConditionedQuery.h @@ -38,7 +38,7 @@ class CConditionedQuery : , public IConditionedModelEvent { private: - CObjectPtr m_pTaskWorker; + CObjectPtr m_pTasker; //CObjectPtr m_PropagationEngine; CObject *m_pConditionedQueryResult; std::vector m_conditionedModels; diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.cpp b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.cpp index 3db7601..1bb8eb1 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.cpp +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.cpp @@ -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; diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.h b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.h index 0c49780..2956213 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.h +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/ContextModel.h @@ -38,7 +38,7 @@ class CContextModel : , public IEvent { private: - CObjectPtr m_pTaskWorker; + CObjectPtr m_pTasker; CObjectPtr m_pEvaluationEngine; CObjectPtr m_pParentModel; ModelPropertyVec m_modelProperties; diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.cpp b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.cpp index ca93057..165c42e 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.cpp +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.cpp @@ -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; diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.h b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.h index 0ccb99f..768010a 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.h +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/EvaluationEngine.h @@ -43,7 +43,7 @@ private: CSimpleMutex m_mtxTriggerId; std::map m_mapTriggers; CSimpleMutex m_mtxDataRelation; - CTaskWorker m_taskWorker; + CObjectPtr m_pTasker; SSMRESULT executeSQL_NoReturn(IN std::string strSQL); diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.cpp b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.cpp index 987a014..770a0ca 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.cpp +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.cpp @@ -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 *pContextModel; - std::map::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::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)); diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.h b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.h index 48b3c1e..9a3fd14 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.h +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/PropagationEngine.h @@ -43,7 +43,7 @@ class CPropagationEngine : , public IResourceEvent { private: - CObjectPtr m_pTaskWorker; + CObjectPtr m_pTasker; CObjectPtr m_pEvaluationEngine; CObjectPtr m_pRootModel; @@ -87,6 +87,8 @@ private: void terminateEngine(); + SSMRESULT updateDeviceInfo(IN ISSMResource *pSSMResource, OUT int *deviceId); + public: SSMRESULT finalConstruct(); diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp index 2e5af43..fb1e1ef 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.cpp @@ -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::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 { diff --git a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.h b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.h index 6115e58..31f4ed5 100644 --- a/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.h +++ b/service/soft-sensor-manager/SSMCore/src/QueryProcessor/QueryEngine.h @@ -49,7 +49,7 @@ private: int m_cqid; IQueryEngineEvent *m_pQueryEngineEvent; std::map m_contextQueries; - CTaskWorker m_taskWorker; + CObjectPtr m_pTasker; private: SSMRESULT processQueryResult(IN int userTriggerId, IN std::vector *result); diff --git a/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.cpp b/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.cpp index 1dbb12d..c78c29b 100644 --- a/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.cpp +++ b/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.cpp @@ -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 *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(objectID, ppObject)); + } + else if (IsEqualOID(OID_IWorkerThread, objectID)) + { + SSM_CLEANUP_ASSERT(CreateNewObject(objectID, ppObject)); + } + else if(IsEqualOID(OID_IThreadPool, objectID)) { SSM_CLEANUP_ASSERT(CreateNewObject(objectID, ppObject)); } @@ -342,8 +376,8 @@ SSMRESULT CreateGlobalInstanceRepo() SSM_CLEANUP_NULL_ASSERT(g_mtxGlobalInstance); g_globalInstance = new std::map(); 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; } diff --git a/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.h b/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.h index 58f922f..989bc4a 100644 --- a/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.h +++ b/service/soft-sensor-manager/SSMCore/src/SSMInterface/SoftSensorManager.h @@ -44,7 +44,6 @@ class CSoftSensorManager : private: CObjectPtr m_pContextRepository; CObjectPtr m_pPropagationEngine; - CObjectPtr m_pThreadPool; CObjectPtr m_pResponseReactor; public: diff --git a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.cpp b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.cpp index ab0202d..648be81 100644 --- a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.cpp +++ b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.cpp @@ -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) { //LOGE("ADDOUTPUT"); std::map::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 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 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 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 *sList, const std::string str, ISSMResource **ppResource) @@ -222,9 +222,9 @@ SSMRESULT CContextExecutor::findString(std::vector *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 *sList, const return ret; } -std::map > CContextExecutor::getPreparedContextList(std::string lowContextName) +std::map > CContextExecutor::getPreparedContextList(std::string primitiveSensor) { - //check m_relatedContextModel / apply timestamp - - std::vector relatedHigherContextList = m_relatedContextModel[lowContextName]; + //check m_relatedSoftSensor / apply timestamp std::map > 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 inputList = m_registeredResources[highContextName]->inputList; + std::vector inputList = m_registeredResources[softSensorName]->inputList; std::vector 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 lowerData = m_storedLowerContextData[inputList.at(j)]; - for (unsigned k = 0; k < lowerData.size(); k++) + std::vector 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 > CContextExecutor::getPreparedC //Data from every primitive sensors int CContextExecutor::onEvent(std::string type, TypeofEvent callType, std::vector 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 > 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 >::iterator iter = readyContextList.begin(); for (; iter != readyContextList.end(); ++iter) { - std::string highContextName = iter->first; + std::string softSensorName = iter->first; std::vector 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 *highList = &m_relatedContextModel[pLowerResource->type]; - for(unsigned int j = 0 ; j < highList->size() ; ++ j) + std::vector *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 inputData,std::string highContextName ) +void CContextExecutor::runLogic(std::vector 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 diff --git a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.h b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.h index c2ef4df..5626442 100644 --- a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.h +++ b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextExecutor.h @@ -42,21 +42,21 @@ class CContextExecutor : , public IThreadClient { private: - CObjectPtr m_pTaskWorker; + CObjectPtr m_pTasker; CObjectPtr m_pContextRepository; CObjectPtr m_pContextDataReader; /** - * @brief Context model data from lower layer + * @brief Sensor data from primitive sensors */ - std::map > m_storedLowerContextData; + std::map > 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 > m_relatedContextModel; + std::map > 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 *data, int *pLastIndex); + void getDataFromDatabase(IN std::string modelName, IN int startIndex, IN int count, OUT std::vector *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 ctxData); + int onEvent(IN std::string deviceID, IN TypeofEvent callType, IN std::vector 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 *sList, IN const std::string str, OUT ISSMResource **ppResource); - std::map > getPreparedContextList(IN std::string lowContextName); - void runLogic(IN std::vector inputData,IN std::string highContextName); + std::map > getPreparedContextList(IN std::string primitiveSensor); + void runLogic(IN std::vector 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 data); + std::string checkError(IN std::vector data); }; diff --git a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.cpp b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.cpp index fc269c0..e8a2fdf 100644 --- a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.cpp +++ b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.cpp @@ -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 CContextRepository::loadXMLFromString(char *xmlData) +SSMRESULT CContextRepository::loadXMLFromString(char *xmlData, std::vector *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 CContextRepository::loadXMLFromString(char *xmlData) rapidxml::xml_node< char > *subItem2; rapidxml::xml_node< char > *subItem3; - std::vector 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 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 CContextRepository::loadXMLFromFile(const char *strFile ) +SSMRESULT CContextRepository::loadXMLFromFile(std::string descriptionFilePath, std::vector *dataList) { - std::basic_ifstream< char > xmlFile( strFile ); - std::vector 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 *pHighLevelList) +SSMRESULT CContextRepository::getSoftSensorList(OUT std::vector *pSoftSensorList) { SSMRESULT res = SSM_E_FAIL; - std::vector dict = loadXMLFromFile(HIGH_LOCATION); - res = makeSSMResourceListForDictionaryData("HIGH", dict, pHighLevelList); + std::vector 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 *pLowLevelList) +SSMRESULT CContextRepository::getPrimitiveSensorList(OUT std::vector *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 dataList, std::vector *pList) +SSMRESULT CContextRepository::makeSSMResourceListForDictionaryData(std::vector dataList, std::vector *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 diff --git a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.h b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.h index cb863fc..f1e9aa1 100644 --- a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.h +++ b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ContextRepository.h @@ -47,6 +47,8 @@ private: std::string m_name; std::string m_type; std::vector 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 *pSoftSensorList - High level context list + * @param [out] std::vector *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 *pPrimitiveSensorList - Low level context list + * @param [out] std::vector *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 dataList, OUT std::vector *pList) ; - std::vector loadXMLFromString(IN char *xmlData); - std::vector loadXMLFromFile(IN const char *strFile ); + SSMRESULT makeSSMResourceListForDictionaryData(IN std::vector dataList, OUT std::vector *pList) ; + SSMRESULT loadXMLFromFile(IN std::string descriptionFilePath, IN std::vector *dataList); + SSMRESULT loadXMLFromString(IN char *xmlData, IN std::vector *dataList); + SSMRESULT GetCurrentPath(OUT std::string *path); }; #endif \ No newline at end of file diff --git a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp index 0206bd8..278937e 100644 --- a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp +++ b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.cpp @@ -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 resource) pMessage[0] = RESOURCE_DISCOVER_REQUESTPROFILE; pMessage[1] = (int)new std::shared_ptr(resource); - m_pTaskWorker->addTask(this, pMessage); + m_pTasker->addTask(this, pMessage); } } diff --git a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h index af8550b..6638ca3 100644 --- a/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h +++ b/service/soft-sensor-manager/SSMCore/src/SensorProcessor/ResourceFinder.h @@ -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 m_pTaskWorker; + CObjectPtr m_pTasker; std::shared_ptr m_pResource; IThreadClient *m_pResourceFinderClient; IEvent *m_pEvent; @@ -186,7 +186,7 @@ private: OC::OCPlatform *m_pPlatform; CObjectPtr m_pResourceConnectivity; IResourceFinderEvent *m_pResourceFinderEvent; - CObjectPtr m_pTaskWorker; + CObjectPtr m_pTasker; std::map m_mapResourceHandler; };