diff options
author | jackpoz <giacomopoz@gmail.com> | 2013-08-25 13:48:55 +0100 |
---|---|---|
committer | Nay <dnpd.dd@gmail.com> | 2013-08-25 13:48:55 +0100 |
commit | e96aa444b07eb6d9b96b37bcef7742ad96225fb4 (patch) | |
tree | 3636b354a949b6cd63e67b4f35985a7a72330bcd /src/server/shared/Threading/Threading.cpp | |
parent | 174efdf05f62ceb33fb33c9a4aa89c3890153c20 (diff) |
Core/Threading: Fix race condition in Thread
Increment the reference count of m_task in Thread::start() before spawning the actual Thread that will execute the task, otherwise the thread might finish, decRef the task and delete it.
Valgrind log of the issue:
Invalid read of size 8
at 0x1314CAD: ACE_Atomic_Op_GCC<long>::operator++() (Atomic_Op_GCC_T.inl:34)
by 0x15933FB: ACE_Based::Runnable::incReference() (Threading.h:36)
by 0x1592D2D: ACE_Based::Thread::start() (Threading.cpp:136)
by 0x1592C37: ACE_Based::Thread::Thread(ACE_Based::Runnable*) (Threading.cpp:111)
by 0xF6C463: Master::Run() (Master.cpp:195)
by 0xF725D0: main (Main.cpp:142)
Address 0x26137278 is 8 bytes inside a block of size 24 free'd
at 0x4C2B59C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0xF67FDB: RARunnable::~RARunnable() (RARunnable.cpp:55)
by 0x1593441: ACE_Based::Runnable::decReference() (Threading.h:40)
by 0x1592E92: ACE_Based::Thread::ThreadTask(void*) (Threading.cpp:186)
by 0x515EA35: ACE_OS_Thread_Adapter::invoke() (in /usr/lib/libACE-6.0.3.so)
by 0x5F19F8D: start_thread (pthread_create.c:311)
by 0x6A46E1C: clone (clone.S:113)
Closes #10619
Diffstat (limited to 'src/server/shared/Threading/Threading.cpp')
-rw-r--r-- | src/server/shared/Threading/Threading.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/server/shared/Threading/Threading.cpp b/src/server/shared/Threading/Threading.cpp index bd96c359616..34a7bf8bb9d 100644 --- a/src/server/shared/Threading/Threading.cpp +++ b/src/server/shared/Threading/Threading.cpp @@ -62,7 +62,7 @@ ThreadPriority::ThreadPriority() //since we have only 7(seven) values in enum Priority //and 3 we know already (Idle, Normal, Realtime) so //we need to split each list [Idle...Normal] and [Normal...Realtime] - //into ¹ piesces + //into piecies const size_t _divider = 4; size_t _div = (norm_pos - min_pos) / _divider; if (_div == 0) @@ -130,10 +130,13 @@ bool Thread::start() if (m_task == 0 || m_iThreadId != 0) return false; + // incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task + m_task->incReference(); + bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0); - if (res) - m_task->incReference(); + if (!res) + m_task->decReference(); return res; } |