[prev in list] [next in list] [prev in thread] [next in thread]
List: sptk-commits
Subject: r1036 - in trunk: sptk4 src/utils
From: alexey () mail ! total-knowledge ! com
Date: 2009-10-30 2:39:59
Message-ID: courier.000000004AEA51FF.00005D38 () mail ! total-knowledge ! com
[Download RAW message or body]
Author: alexey
Date: 2009-10-29 19:39:59 -0700 (Thu, 29 Oct 2009)
New Revision: 1036
Modified:
trunk/sptk4/CSafeList.h
trunk/sptk4/CSafeQueue.h
trunk/sptk4/CThread.h
trunk/sptk4/CThreadManager.h
trunk/src/utils/CThread.cpp
trunk/src/utils/CThreadManager.cpp
Log:
Removed some race conditions
Modified: trunk/sptk4/CSafeList.h
===================================================================
--- trunk/sptk4/CSafeList.h 2009-10-30 02:37:16 UTC (rev 1035)
+++ trunk/sptk4/CSafeList.h 2009-10-30 02:39:59 UTC (rev 1036)
@@ -54,7 +54,7 @@
/// thread).
template <class T>
class CSafeList {
- std::list<T> m_list; ///< List of the Ts
+ std::list<T>* m_list; ///< List of the Ts
CWaiter m_lock; ///< Lock to protect list operations
CSemaphore m_popSemaphore; ///< Semaphore to waiting for an item if list is empty
CSemaphore m_pushSemaphore; ///< Semaphore to wait if list is full
@@ -73,8 +73,15 @@
CSafeList(uint32_t maxListItems=0) :
m_pushSemaphore(maxListItems), m_maxListItems(maxListItems)
{
+ m_list = new std::list<T>;
}
+ ~CSafeList()
+ {
+ GUARD(m_lock);
+ delete m_list;
+ }
+
/// @brief Places the item to the list tail
/// @param item T&, a new list item
void push_back(const T& item)
@@ -83,7 +90,7 @@
m_pushSemaphore.wait();
{
CGuard guard(m_lock);
- m_list.push_back(item);
+ m_list->push_back(item);
}
m_popSemaphore.post();
}
@@ -96,7 +103,7 @@
m_pushSemaphore.wait();
{
CGuard guard(m_lock);
- m_list.push_front(item);
+ m_list->push_front(item);
}
m_popSemaphore.post();
}
@@ -114,8 +121,8 @@
if (m_popSemaphore.wait(timeoutMS)) {
try {
CGuard guard(m_lock);
- item = m_list.front();
- m_list.pop_front();
+ item = m_list->front();
+ m_list->pop_front();
if (m_maxListItems)
m_pushSemaphore.post();
return true;
@@ -139,8 +146,8 @@
if (m_popSemaphore.wait(timeoutMS)) {
try {
CGuard guard(m_lock);
- item = m_list.back();
- m_list.pop_back();
+ item = m_list->back();
+ m_list->pop_back();
if (m_maxListItems)
m_pushSemaphore.post();
return true;
@@ -160,7 +167,7 @@
bool foreach(Method* method, void* parameter=NULL)
{
iterator itor;
- for (itor = m_list.begin(); itor != m_list.end(); itor++) {
+ for (itor = m_list->begin(); itor != m_list->end(); itor++) {
if (!method(*itor, parameter))
return false;
}
@@ -171,39 +178,39 @@
void erase(T& item)
{
GUARD(m_lock);
- iterator itor = find(m_list.begin(),m_list.end(),item);
- if (itor != m_list.end())
- m_list.erase(itor);
+ iterator itor = find(m_list->begin(),m_list->end(),item);
+ if (itor != m_list->end())
+ m_list->erase(itor);
}
/// @brief Removes an item from the list
bool exists(T& item)
{
GUARD(m_lock);
- iterator itor = find(m_list.begin(),m_list.end(),item);
- return (itor != m_list.end());
+ iterator itor = find(m_list->begin(),m_list->end(),item);
+ return (itor != m_list->end());
}
/// @brief Clears the list
void clear()
{
GUARD(m_lock);
- while (!m_list.empty())
- m_list.pop_front();
+ while (!m_list->empty())
+ m_list->pop_front();
}
/// @brief Returns true if the list is empty
bool empty()
{
GUARD(m_lock);
- return m_list.empty();
+ return m_list->empty();
}
/// @brief Returns number of items in the list
size_t size()
{
GUARD(m_lock);
- return m_list.size();
+ return m_list->size();
}
};
/// @}
Modified: trunk/sptk4/CSafeQueue.h
===================================================================
--- trunk/sptk4/CSafeQueue.h 2009-10-30 02:37:16 UTC (rev 1035)
+++ trunk/sptk4/CSafeQueue.h 2009-10-30 02:39:59 UTC (rev 1036)
@@ -54,7 +54,7 @@
/// thread).
template <class T>
class CSafeQueue {
- std::queue<T> m_queue; ///< Queue of the Ts
+ std::queue<T>* m_queue; ///< Queue of the Ts
CWaiter m_lock; ///< Lock to protect queue operations
CSemaphore m_popSemaphore; ///< Semaphore to waiting for an item if queue is empty
CSemaphore m_pushSemaphore; ///< Semaphore to wait if queue is full
@@ -68,8 +68,17 @@
CSafeQueue(uint32_t maxQueueItems=0) :
m_pushSemaphore(maxQueueItems), m_maxQueueItems(maxQueueItems)
{
+ m_queue = new std::queue<T>;
}
+ /// @brief Destructor
+ ~CSafeQueue()
+ {
+ GUARD(m_lock);
+ delete m_queue;
+ m_queue = 0;
+ }
+
/// @brief Places the item to the queue tail
/// @param item T&, a new queue item
void push(const T& item)
@@ -78,7 +87,7 @@
m_pushSemaphore.wait();
{
CGuard guard(m_lock);
- m_queue.push(item);
+ m_queue->push(item);
}
m_popSemaphore.post();
}
@@ -96,8 +105,8 @@
if (m_popSemaphore.wait(timeoutMS)) {
try {
CGuard guard(m_lock);
- item = m_queue.front();
- m_queue.pop();
+ item = m_queue->front();
+ m_queue->pop();
if (m_maxQueueItems)
m_pushSemaphore.post();
return true;
@@ -112,22 +121,22 @@
void clear()
{
GUARD(m_lock);
- while (!m_queue.empty())
- m_queue.pop();
+ while (!m_queue->empty())
+ m_queue->pop();
}
/// @brief Returns true if the queue is empty
bool empty()
{
GUARD(m_lock);
- return m_queue.empty();
+ return m_queue->empty();
}
/// @brief Returns number of items in the queue
size_t size()
{
GUARD(m_lock);
- return m_queue.size();
+ return m_queue->size();
}
};
/// @}
Modified: trunk/sptk4/CThread.h
===================================================================
--- trunk/sptk4/CThread.h 2009-10-30 02:37:16 UTC (rev 1035)
+++ trunk/sptk4/CThread.h 2009-10-30 02:39:59 UTC (rev 1036)
@@ -37,6 +37,7 @@
#define __CTHREAD_H__
#include <sptk4/CWaiter.h>
+#include <sptk4/CGuard.h>
#include <sptk4/CBaseLog.h>
#include <sptk4/CStrings.h>
@@ -53,6 +54,8 @@
/// by overwriting threadFunction().
class CThread {
friend class CThreadManager;
+ CWaiter m_lock; ///< Lock to protect data members
+ CThreadManager* m_owner; ///< Optional thread owner
protected:
bool m_terminated; ///< Flag: is the thread terminated?
bool m_running; ///< Flag: is the thread running?
@@ -60,11 +63,9 @@
std::string m_name; ///< Thread name
CBaseLog* m_threadLog; ///< Optional thread log (NULL for no logging)
uint32_t m_stackSize; ///< Thread stack size (0 for system default)
- CThreadManager* m_owner; ///< Optional thread owner
#ifndef _WIN32
pthread_t m_thread; ///< Thread handle
#else
-
HANDLE m_thread; ///< Thread handle
HANDLE m_timer; ///< Thread timer handle
#endif
@@ -96,6 +97,9 @@
/// The thread function. Should be overwritten by the derived class.
virtual void threadFunction() = 0;
+ /// @brief Sets the thread manager that owns this thread
+ void setOwner(CThreadManager* owner);
+
public:
/// Constructor
@@ -116,11 +120,13 @@
/// Returns true if the thread is terminated
bool terminated() {
+ GUARD(m_lock);
return m_terminated;
}
/// Returns true if the thread is running
bool running() {
+ GUARD(m_lock);
return m_running;
}
Modified: trunk/sptk4/CThreadManager.h
===================================================================
--- trunk/sptk4/CThreadManager.h 2009-10-30 02:37:16 UTC (rev 1035)
+++ trunk/sptk4/CThreadManager.h 2009-10-30 02:39:59 UTC (rev 1036)
@@ -72,6 +72,7 @@
CSafeList<PCThread> m_threads; ///< Threads list
CSafeQueue<PCThread> m_terminatedThreads; ///< Terminated threads list
CProxyLog* m_log; ///< Shared log
+ bool m_shutdown; ///< True during thread manager shutdown
protected:
/// @brief Registers completed thread termination
Modified: trunk/src/utils/CThread.cpp
===================================================================
--- trunk/src/utils/CThread.cpp 2009-10-30 02:37:16 UTC (rev 1035)
+++ trunk/src/utils/CThread.cpp 2009-10-30 02:39:59 UTC (rev 1036)
@@ -73,6 +73,7 @@
void CThread::threadCleanup(void *p)
{
CThread *thread = (CThread *) p;
+ GUARD(thread->m_lock);
thread->onThreadExit();
}
@@ -91,7 +92,10 @@
{
if (m_thread) {
if (m_politeMode) {
- m_terminated = true;
+ {
+ GUARD(m_lock);
+ m_terminated = true;
+ }
#ifndef _WIN32
// wait till the thread is stopping
pthread_join(m_thread, 0);
@@ -112,6 +116,7 @@
void CThread::terminate()
{
+ GUARD(m_lock);
if (m_terminated)
return;
m_terminated = true;
@@ -157,24 +162,43 @@
void CThread::runThread()
{
- m_running = true;
+ {
+ GUARD(m_lock);
+ m_running = true;
+ }
+
threadFunction();
- m_running = false;
- m_terminated = true;
- if (m_owner)
- m_owner->registerTerminated(this);
+ {
+ GUARD(m_lock);
+ m_running = false;
+ m_terminated = true;
+ if (m_owner) {
+ m_owner->registerTerminated(this);
+ m_owner = NULL;
+ }
+ }
+
destroyThread();
}
void CThread::run()
{
- m_terminated = false;
- m_running = true;
+ {
+ GUARD(m_lock);
+ m_terminated = false;
+ m_running = true;
+ }
createThread();
}
+void CThread::setOwner(CThreadManager* owner)
+{
+ GUARD(m_lock);
+ m_owner = owner;
+}
+
void CThread::msleep(int msec)
{
#ifndef _WIN32
Modified: trunk/src/utils/CThreadManager.cpp
===================================================================
--- trunk/src/utils/CThreadManager.cpp 2009-10-30 02:37:16 UTC (rev 1035)
+++ trunk/src/utils/CThreadManager.cpp 2009-10-30 02:39:59 UTC (rev 1036)
@@ -40,7 +40,7 @@
using namespace sptk;
CThreadManager::CThreadManager(CBaseLog* log) :
- CThread("Thread Manager")
+ CThread("Thread Manager"), m_shutdown(false)
{
if (log) {
m_log = new CProxyLog(*log);
@@ -53,6 +53,10 @@
CThreadManager::~CThreadManager()
{
+ {
+ GUARD(m_lock);
+ m_shutdown = true;
+ }
clear();
if (m_log)
delete m_log;
@@ -61,8 +65,10 @@
void CThreadManager::registerTerminated(CThread* thread)
{
GUARD(*this);
- erase(thread);
- m_terminatedThreads.push(thread);
+ if (!m_shutdown) {
+ m_threads.erase(thread);
+ m_terminatedThreads.push(thread);
+ }
}
void CThreadManager::threadFunction()
@@ -110,7 +116,7 @@
void CThreadManager::erase(CThread* thread)
{
m_threads.erase(thread);
- thread->m_owner = NULL;
+ thread->setOwner(NULL);
}
void CThreadManager::run()
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic