1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
20 #include "ThreadManager.h"
22 CSimpleMutex::CSimpleMutex()
25 InitializeCriticalSection(&m_criticalSection);
27 pthread_mutexattr_init(&m_mutexAttribute);
28 pthread_mutexattr_settype(&m_mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
29 pthread_mutex_init(&m_mutex, &m_mutexAttribute);
31 #error WIN32 or LINUX tag must be defined
35 CSimpleMutex::~CSimpleMutex()
38 DeleteCriticalSection(&m_criticalSection);
40 pthread_mutex_destroy(&m_mutex);
41 pthread_mutexattr_destroy(&m_mutexAttribute);
43 #error WIN32 or LINUX tag must be defined
47 void CSimpleMutex::lock()
50 EnterCriticalSection(&m_criticalSection);
52 pthread_mutex_lock(&m_mutex);
54 #error WIN32 or LINUX tag must be defined
58 void CSimpleMutex::unlock()
61 LeaveCriticalSection(&m_criticalSection);
63 pthread_mutex_unlock(&m_mutex);
65 #error WIN32 or LINUX tag must be defined
70 CSemaphore::CSemaphore()
74 CSemaphore::~CSemaphore()
78 SSMRESULT CSemaphore::initialize()
81 hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
83 if (hSemaphore == NULL)
86 if (sem_init(&hSemaphore, 0, 0) == -1)
89 #error WIN32 or LINUX tag must be defined
94 SSMRESULT CSemaphore::destroy()
97 if (CloseHandle(hSemaphore) == FALSE)
100 if (sem_destroy(&hSemaphore) == -1)
103 #error WIN32 or LINUX tag must be defined
108 SSMRESULT CSemaphore::take()
111 if (WaitForSingleObject(hSemaphore, INFINITE) == WAIT_OBJECT_0)
116 if (sem_wait(&hSemaphore) == -1)
121 #error WIN32 or LINUX tag must be defined
125 SSMRESULT CSemaphore::give()
128 if (ReleaseSemaphore(hSemaphore, 1, NULL) != 0)
133 if (sem_post(&hSemaphore) == -1)
138 #error WIN32 or LINUX tag must be defined
143 bool CWorkerThread::getTask(ClientEntry *clientEntry)
145 m_mtxClientEntry.lock();
147 if (m_ClientEntry.empty())
149 m_mtxClientEntry.unlock();
150 //Sleep if there are no more tasks
155 m_mtxClientEntry.unlock();
159 m_mtxThreadTerm.lock();
160 if (m_bThreadTerm == true)
162 m_mtxThreadTerm.unlock();
165 m_mtxThreadTerm.unlock();
167 m_mtxClientEntry.lock();
168 if (!m_ClientEntry.empty())
170 *clientEntry = m_ClientEntry.front();
171 m_ClientEntry.pop_front();
173 m_mtxClientEntry.unlock();
178 void CWorkerThread::worker()
180 ClientEntry clientEntry;
182 m_semTask.initialize();
184 //Thread Creation completed
188 while (getTask(&clientEntry))
190 if (clientEntry.pClient)
192 clientEntry.pClient->onExecute(clientEntry.pArg);
193 clientEntry.pClient->onTerminate(clientEntry.pArg);
195 SAFE_RELEASE(clientEntry.pClient);
198 //Clean all remaining tasks
199 m_mtxClientEntry.lock();
200 //Remove all tasks from queue
201 for (std::list<ClientEntry>::iterator itor = m_ClientEntry.begin();
202 itor != m_ClientEntry.end(); ++itor)
204 ClientEntry clientEntry = *itor;
205 clientEntry.pClient->onTerminate(clientEntry.pArg);
206 SAFE_RELEASE(clientEntry.pClient);
208 m_ClientEntry.clear();
209 m_mtxClientEntry.unlock();
216 SSMRESULT CWorkerThread::initialize()
218 SSMRESULT res = SSM_E_FAIL;
220 //Create thread and wait for jobs
222 m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_worker,
225 if (m_hThread == NULL)
230 if (pthread_create(&m_hThread, NULL, (void *(*)(void *))_worker, (void *)this) != 0)
235 #error WIN32 or LINUX tag must be defined
237 //Wait till thread created
238 SSM_CLEANUP_ASSERT(m_semInit.take());
239 SSM_CLEANUP_ASSERT(m_semInit.destroy());
245 SSMRESULT CWorkerThread::terminate()
247 SSMRESULT res = SSM_E_FAIL;
249 //Let worker destroyed
250 m_mtxThreadTerm.lock();
251 m_bThreadTerm = true;
252 m_mtxThreadTerm.unlock();
254 SSM_CLEANUP_ASSERT(m_semTask.give());
256 SSM_CLEANUP_ASSERT(m_semTerm.take());
257 SSM_CLEANUP_ASSERT(m_semTerm.destroy());
260 if (m_hThread != NULL)
262 CloseHandle(m_hThread);
265 pthread_detach(m_hThread);
267 #error WIN32 or LINUX tag must be defined
275 SSMRESULT CWorkerThread::finalConstruct()
277 SSMRESULT res = SSM_E_FAIL;
279 m_bThreadTerm = false;
281 SSM_CLEANUP_ASSERT(m_semInit.initialize());
282 SSM_CLEANUP_ASSERT(m_semTerm.initialize());
288 void CWorkerThread::finalRelease()
292 SSMRESULT CWorkerThread::addTask(IThreadClient *pThreadClient, void *param)
294 ClientEntry clientEntry;
296 pThreadClient->addRef();
297 clientEntry.pClient = pThreadClient;
298 clientEntry.pArg = param;
300 m_mtxClientEntry.lock();
301 if (m_ClientEntry.empty())
305 m_ClientEntry.push_back(clientEntry);
306 //Let the task worker know, we just added task
307 m_mtxClientEntry.unlock();
313 SSMRESULT CTasker::finalConstruct()
315 SSMRESULT res = SSM_E_FAIL;
317 SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IThreadPool, (IBase **)&m_pThreadPool));
319 SSM_CLEANUP_ASSERT(m_pThreadPool->createWorkerThread(&m_pWorkerThread));
325 void CTasker::finalRelease()
329 SSMRESULT CTasker::addTask(IThreadClient *pThreadClient, void *param)
331 return m_pWorkerThread->addTask(pThreadClient, param);
335 SSMRESULT CThreadPool::finalConstruct()
340 void CThreadPool::finalRelease()
342 for (std::vector<IWorkerThread *>::iterator itor = m_lstWorkerThread.begin();
343 itor != m_lstWorkerThread.end(); ++itor)
349 SSMRESULT CThreadPool::createWorkerThread(OUT IWorkerThread **ppWorkerThread)
351 SSMRESULT res = SSM_E_FAIL;
353 IWorkerThread *pWorkerThread = NULL;
355 SSM_CLEANUP_NULL_ASSERT(ppWorkerThread);
357 SSM_CLEANUP_ASSERT(CreateInstance(OID_IWorkerThread, (IBase **)&pWorkerThread));
358 SSM_CLEANUP_ASSERT(pWorkerThread->initialize());
359 SSM_CLEANUP_ASSERT(pWorkerThread->queryInterface(OID_IWorkerThread, (IBase **)ppWorkerThread));
360 m_lstWorkerThread.push_back(pWorkerThread);
366 SSMRESULT CThreadPool::destroyThreadPool()
368 SSMRESULT res = SSM_E_FAIL;
370 for (std::vector<IWorkerThread *>::iterator itor = m_lstWorkerThread.begin();
371 itor != m_lstWorkerThread.end(); ++itor)
373 SSM_CLEANUP_ASSERT((*itor)->terminate());