mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 08:03:50 +00:00
Fix /logout hang caused by blocking worker thread joins
unloadAll() joins worker threads which blocks if they're mid-tile (prepareTile can take seconds for heavy ADTs). Replace with softReset() which clears tile data, queues, and water surfaces without stopping worker threads — workers find empty queues and idle naturally.
This commit is contained in:
parent
872b10fe68
commit
26a685187e
3 changed files with 30 additions and 2 deletions
|
|
@ -212,6 +212,7 @@ public:
|
||||||
* Unload all tiles
|
* Unload all tiles
|
||||||
*/
|
*/
|
||||||
void unloadAll();
|
void unloadAll();
|
||||||
|
void softReset(); // Clear tile data without stopping worker threads (non-blocking)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Precache a set of tiles (for taxi routes, etc.)
|
* Precache a set of tiles (for taxi routes, etc.)
|
||||||
|
|
|
||||||
|
|
@ -661,9 +661,10 @@ void Application::logoutToLogin() {
|
||||||
if (auto* m2 = renderer->getM2Renderer()) {
|
if (auto* m2 = renderer->getM2Renderer()) {
|
||||||
m2->clear();
|
m2->clear();
|
||||||
}
|
}
|
||||||
// Unload all terrain tiles + water surfaces so next world entry starts fresh
|
// Clear terrain tile tracking + water surfaces so next world entry starts fresh.
|
||||||
|
// Use softReset() instead of unloadAll() to avoid blocking on worker thread joins.
|
||||||
if (auto* terrain = renderer->getTerrainManager()) {
|
if (auto* terrain = renderer->getTerrainManager()) {
|
||||||
terrain->unloadAll();
|
terrain->softReset();
|
||||||
}
|
}
|
||||||
if (auto* questMarkers = renderer->getQuestMarkerRenderer()) {
|
if (auto* questMarkers = renderer->getQuestMarkerRenderer()) {
|
||||||
questMarkers->clear();
|
questMarkers->clear();
|
||||||
|
|
|
||||||
|
|
@ -1296,6 +1296,32 @@ void TerrainManager::unloadAll() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerrainManager::softReset() {
|
||||||
|
// Clear queues (workers may still be running — they'll find empty queues)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(queueMutex);
|
||||||
|
loadQueue.clear();
|
||||||
|
while (!readyQueue.empty()) readyQueue.pop();
|
||||||
|
}
|
||||||
|
pendingTiles.clear();
|
||||||
|
finalizingTiles_.clear();
|
||||||
|
placedDoodadIds.clear();
|
||||||
|
|
||||||
|
LOG_INFO("Soft-resetting terrain (clearing tiles + water, workers stay alive)");
|
||||||
|
loadedTiles.clear();
|
||||||
|
failedTiles.clear();
|
||||||
|
|
||||||
|
currentTile = {-1, -1};
|
||||||
|
lastStreamTile = {-1, -1};
|
||||||
|
|
||||||
|
if (terrainRenderer) {
|
||||||
|
terrainRenderer->clear();
|
||||||
|
}
|
||||||
|
if (waterRenderer) {
|
||||||
|
waterRenderer->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TileCoord TerrainManager::worldToTile(float glX, float glY) const {
|
TileCoord TerrainManager::worldToTile(float glX, float glY) const {
|
||||||
auto [tileX, tileY] = core::coords::worldToTile(glX, glY);
|
auto [tileX, tileY] = core::coords::worldToTile(glX, glY);
|
||||||
return {tileX, tileY};
|
return {tileX, tileY};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue