aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjackpoz <giacomopoz@gmail.com>2013-09-01 18:49:49 +0200
committerjackpoz <giacomopoz@gmail.com>2013-09-01 18:49:49 +0200
commite1e1067d172f9b1a6ba770ca6ae53a07dbc9d56f (patch)
treec4538f06a9b2c110efbfdb596024a81dbd078483
parent1501e958767ab0cddc5d501796fdcb63bf98a87c (diff)
Core/Thread: Fix race condition in FreezeDetectorRunnable
Fix race condition by replacing a static volatile uint32 with proper atomic thread-safe ACE_Atomic_Op<ACE_Thread_Mutex, uint32>, incremented in WorldRunnable::run() at each world loop and read in FreezeDetectorRunnable::run(). Helgrind log: Possible data race during read of size 4 at 0x2400D54 by thread #12 Locks held: none at 0x100FEA6: FreezeDetectorRunnable::run() (Master.cpp:106) by 0x1637892: ACE_Based::Thread::ThreadTask(void*) (Threading.cpp:186) by 0x518F555: ACE_OS_Thread_Adapter::invoke() (OS_Thread_Adapter.cpp:103) by 0x4C2B5AD: mythread_wrapper (hg_intercepts.c:219) by 0x61DAB4F: start_thread (pthread_create.c:304) by 0x6C69A7C: clone (clone.S:112) This conflicts with a previous write of size 4 by thread #9 Locks held: none at 0x100C23E: WorldRunnable::run() (WorldRunnable.cpp:55) by 0x1637892: ACE_Based::Thread::ThreadTask(void*) (Threading.cpp:186) by 0x518F555: ACE_OS_Thread_Adapter::invoke() (OS_Thread_Adapter.cpp:103) by 0x4C2B5AD: mythread_wrapper (hg_intercepts.c:219) by 0x61DAB4F: start_thread (pthread_create.c:304) by 0x6C69A7C: clone (clone.S:112)
-rw-r--r--src/server/game/World/World.cpp2
-rw-r--r--src/server/game/World/World.h2
-rw-r--r--src/server/worldserver/Master.cpp5
3 files changed, 5 insertions, 4 deletions
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 2bc4f3a0258..12ec033dfa7 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -83,7 +83,7 @@
ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
-volatile uint32 World::m_worldLoopCounter = 0;
+ACE_Atomic_Op<ACE_Thread_Mutex, uint32> World::m_worldLoopCounter = 0;
float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index bf90b5ac01a..d4d9c4e2431 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -514,7 +514,7 @@ struct CharacterNameData
class World
{
public:
- static volatile uint32 m_worldLoopCounter;
+ static ACE_Atomic_Op<ACE_Thread_Mutex, uint32> m_worldLoopCounter;
World();
~World();
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
index b2a6b60ac4f..d9b97cfd3f5 100644
--- a/src/server/worldserver/Master.cpp
+++ b/src/server/worldserver/Master.cpp
@@ -103,10 +103,11 @@ public:
ACE_Based::Thread::Sleep(1000);
uint32 curtime = getMSTime();
// normal work
- if (_loops != World::m_worldLoopCounter)
+ uint32 worldLoopCounter = World::m_worldLoopCounter.value();
+ if (_loops != worldLoopCounter)
{
_lastChange = curtime;
- _loops = World::m_worldLoopCounter;
+ _loops = worldLoopCounter;
}
// possible freeze
else if (getMSTimeDiff(_lastChange, curtime) > _delaytime)