Skip to content

Commit

Permalink
fix stale thread-id cache in watchdog after reload
Browse files Browse the repository at this point in the history
  • Loading branch information
rt committed Sep 26, 2017
1 parent a6a8be4 commit 75b7e4a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 45 deletions.
1 change: 1 addition & 0 deletions doc/changelog.txt
Expand Up @@ -15,6 +15,7 @@ Lua:
Misc:
- remove joystick support
- detect hangs during filesystem initialisation
- fix stale thread-id cache in watchdog after reload
- make LuaVFSDownload rescan archives in main thread, and do so when a download finishes (not when one starts)


Expand Down
83 changes: 38 additions & 45 deletions rts/System/Platform/Threading.cpp
Expand Up @@ -29,17 +29,19 @@


namespace Threading {
static std::shared_ptr<Error> threadError;
enum {
THREAD_IDX_MAIN = 0,
THREAD_IDX_LOAD = 1,
THREAD_IDX_SND = 2,
THREAD_IDX_VFSI = 3,
THREAD_IDX_WDOG = 4,
THREAD_IDX_LAST = 5,
};

static bool haveMainThreadID = false;
static bool haveGameLoadThreadID = false;
static bool haveAudioThreadID = false;
static bool haveWatchDogThreadID = false;
static bool cachedThreadIDs[THREAD_IDX_LAST] = {false, false, false, false, false};
static NativeThreadId nativeThreadIDs[THREAD_IDX_LAST] = {};

static NativeThreadId nativeMainThreadID;
static NativeThreadId nativeGameLoadThreadID;
static NativeThreadId nativeAudioThreadID;
static NativeThreadId nativeWatchDogThreadID;
static Error threadError;

thread_local std::shared_ptr<Threading::ThreadControls> threadCtls;

Expand Down Expand Up @@ -296,7 +298,7 @@ namespace Threading {
std::unique_lock<spring::mutex> lock(tempCtls.mutSuspend);
spring::thread localthread(std::bind(Threading::ThreadStart, taskFunc, ppCtlsReturn, &tempCtls));

// Wait so that we know the thread is running and fully initialized before returning.
// wait so that we know the thread is running and fully initialized before returning
tempCtls.condInitialized.wait(lock);
#else
spring::thread localthread(taskFunc);
Expand All @@ -307,51 +309,42 @@ namespace Threading {



void SetMainThread() {
if (!haveMainThreadID) {
haveMainThreadID = true;
// springMainThreadID = spring::this_thread::get_id();
nativeMainThreadID = Threading::GetCurrentThreadId();
}

SetCurrentThreadControls(false);
}

void SetGameLoadThread() {
if (!haveGameLoadThreadID) {
haveGameLoadThreadID = true;
nativeGameLoadThreadID = Threading::GetCurrentThreadId();
}
static void SetThread(unsigned int threadIndex, bool setControls, bool isLoadThread) {
// NOTE:
// the ID's of LOAD and SND always have to be set unconditionally since
// those two threads are joined and respawned when reloading, KISS here
// (while other threads never call Set*Thread more than once making the
// is-cached flags redundant anyway)
if (true || !cachedThreadIDs[threadIndex])
nativeThreadIDs[threadIndex] = Threading::GetCurrentThreadId();

SetCurrentThreadControls(true);
}
cachedThreadIDs[threadIndex] = true;

void SetAudioThread() {
if (!haveAudioThreadID) {
haveAudioThreadID = true;
nativeAudioThreadID = Threading::GetCurrentThreadId();
}
if (!setControls)
return;

SetCurrentThreadControls(false);
SetCurrentThreadControls(isLoadThread);
}

void SetWatchDogThread() {
if (!haveWatchDogThreadID) {
haveWatchDogThreadID = true;
nativeWatchDogThreadID = Threading::GetCurrentThreadId();
}
}
void SetMainThread() { SetThread(THREAD_IDX_MAIN, true, false); }
void SetGameLoadThread() { SetThread(THREAD_IDX_LOAD, true, true); }
void SetAudioThread() { SetThread(THREAD_IDX_SND , true, false); }
void SetFileSysThread() { SetThread(THREAD_IDX_VFSI, true, false); }
void SetWatchDogThread() { SetThread(THREAD_IDX_WDOG, false, false); }

bool IsMainThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeMainThreadID); }
bool IsMainThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeThreadIDs[THREAD_IDX_MAIN]); }
bool IsMainThread( ) { return IsMainThread(Threading::GetCurrentThreadId()); }

bool IsGameLoadThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeGameLoadThreadID); }
bool IsGameLoadThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeThreadIDs[THREAD_IDX_LOAD]); }
bool IsGameLoadThread( ) { return IsGameLoadThread(Threading::GetCurrentThreadId()); }

bool IsAudioThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeAudioThreadID); }
bool IsAudioThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeThreadIDs[THREAD_IDX_SND]); }
bool IsAudioThread( ) { return IsAudioThread(Threading::GetCurrentThreadId()); }

bool IsWatchDogThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeWatchDogThreadID); }
bool IsFileSysThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeThreadIDs[THREAD_IDX_VFSI]); }
bool IsFileSysThread( ) { return IsFileSysThread(Threading::GetCurrentThreadId()); }

bool IsWatchDogThread(NativeThreadId threadID) { return NativeThreadIdsEqual(threadID, nativeThreadIDs[THREAD_IDX_WDOG]); }
bool IsWatchDogThread( ) { return IsWatchDogThread(Threading::GetCurrentThreadId()); }


Expand Down Expand Up @@ -388,7 +381,7 @@ namespace Threading {
}


void SetThreadError(const Error& err) { threadError.reset(new Error(err)); }
Error* GetThreadError() { return (threadError.get()); }
void SetThreadError(const Error& err) { threadError = err; }
Error* GetThreadError() { return &threadError; }
}

4 changes: 4 additions & 0 deletions rts/System/Platform/Threading.h
Expand Up @@ -125,6 +125,7 @@ namespace Threading {
void SetMainThread();
void SetGameLoadThread();
void SetAudioThread();
void SetFileSysThread();
void SetWatchDogThread();

bool IsMainThread();
Expand All @@ -136,6 +137,9 @@ namespace Threading {
bool IsAudioThread();
bool IsAudioThread(NativeThreadId threadID);

bool IsFileSysThread();
bool IsFileSysThread(NativeThreadId threadID);

bool IsWatchDogThread();
bool IsWatchDogThread(NativeThreadId threadID);

Expand Down

0 comments on commit 75b7e4a

Please sign in to comment.