mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-26 21:13:51 +00:00
Fix window close hang from blocking worker thread joins
unloadAll() now uses a 500ms deadline with pthread_timedjoin_np to avoid blocking indefinitely when worker threads are mid-prepareTile (reading MPQ archives / parsing ADT files). Threads that don't finish within the deadline are detached so the app can exit promptly.
This commit is contained in:
parent
26a685187e
commit
e220ce888d
1 changed files with 25 additions and 3 deletions
|
|
@ -1238,13 +1238,35 @@ void TerrainManager::unloadTile(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainManager::unloadAll() {
|
void TerrainManager::unloadAll() {
|
||||||
// Stop worker threads
|
// Signal worker threads to stop and wait briefly for them to finish.
|
||||||
|
// Workers may be mid-prepareTile (reading MPQ / parsing ADT) which can
|
||||||
|
// take seconds, so use a short deadline and detach any stragglers.
|
||||||
if (workerRunning.load()) {
|
if (workerRunning.load()) {
|
||||||
workerRunning.store(false);
|
workerRunning.store(false);
|
||||||
queueCV.notify_all();
|
queueCV.notify_all();
|
||||||
|
|
||||||
|
auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);
|
||||||
for (auto& t : workerThreads) {
|
for (auto& t : workerThreads) {
|
||||||
if (t.joinable()) {
|
if (!t.joinable()) continue;
|
||||||
t.join();
|
// Try a timed wait via polling — std::thread has no timed join.
|
||||||
|
bool joined = false;
|
||||||
|
while (std::chrono::steady_clock::now() < deadline) {
|
||||||
|
// Check if thread finished by trying a native timed join
|
||||||
|
#ifdef __linux__
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
ts.tv_nsec += 50000000; // 50ms
|
||||||
|
if (ts.tv_nsec >= 1000000000) { ts.tv_sec++; ts.tv_nsec -= 1000000000; }
|
||||||
|
if (pthread_timedjoin_np(t.native_handle(), nullptr, &ts) == 0) {
|
||||||
|
joined = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (!joined && t.joinable()) {
|
||||||
|
t.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
workerThreads.clear();
|
workerThreads.clear();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue