aboutsummaryrefslogtreecommitdiff
path: root/src/shared/Threading.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/Threading.cpp')
-rw-r--r--src/shared/Threading.cpp35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/shared/Threading.cpp b/src/shared/Threading.cpp
index 25bd3120c4a..652f468772f 100644
--- a/src/shared/Threading.cpp
+++ b/src/shared/Threading.cpp
@@ -103,6 +103,10 @@ Thread::Thread() : m_task(0), m_iThreadId(0), m_hThreadHandle(0)
Thread::Thread(Runnable* instance) : m_task(instance), m_iThreadId(0), m_hThreadHandle(0)
{
+ // register reference to m_task to prevent it deeltion until destructor
+ if (m_task)
+ m_task->incReference();
+
bool _start = start();
ASSERT (_start);
}
@@ -111,8 +115,9 @@ Thread::~Thread()
{
//Wait();
- // deleted runnable object (owned by Thread)
- delete m_task;
+ // deleted runnable object (if no other references)
+ if (m_task)
+ m_task->decReference();
}
//initialize Thread's class static member
@@ -121,15 +126,20 @@ ThreadPriority Thread::m_TpEnum;
bool Thread::start()
{
- if(m_task == 0 || m_iThreadId != 0)
+ if (m_task == 0 || m_iThreadId != 0)
return false;
- return (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
+ bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
+
+ if (res)
+ m_task->incReference();
+
+ return res;
}
bool Thread::wait()
{
- if(!m_hThreadHandle || !m_task)
+ if (!m_hThreadHandle || !m_task)
return false;
ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1);
@@ -143,7 +153,17 @@ bool Thread::wait()
void Thread::destroy()
{
- ACE_Thread::kill(m_iThreadId, -1);
+ if (!m_iThreadId || !m_task)
+ return;
+
+ if (ACE_Thread::kill(m_iThreadId, -1) != 0)
+ return;
+
+ m_iThreadId = 0;
+ m_hThreadHandle = 0;
+
+ // reference set at ACE_Thread::spawn
+ m_task->decReference();
}
void Thread::suspend()
@@ -161,6 +181,9 @@ ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param)
Runnable * _task = (Runnable*)param;
_task->run();
+ // task execution complete, free referecne added at
+ _task->decReference();
+
return (ACE_THR_FUNC_RETURN)0;
}