From 9ef48d3bab4f6e02b83dd827f20db39690f36d7b Mon Sep 17 00:00:00 2001 From: Emagi Date: Wed, 30 Jul 2025 19:15:47 -0400 Subject: [PATCH] limiting spawn list write lock further --- source/WorldServer/LuaFunctions.cpp | 2 +- source/WorldServer/zoneserver.cpp | 105 ++++++++++++++-------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/source/WorldServer/LuaFunctions.cpp b/source/WorldServer/LuaFunctions.cpp index 253a0a6..890dd18 100644 --- a/source/WorldServer/LuaFunctions.cpp +++ b/source/WorldServer/LuaFunctions.cpp @@ -4707,7 +4707,7 @@ int EQ2Emu_lua_Harvest(lua_State* state) { ((GroundSpawn*)node)->ProcessHarvest(client); if (((GroundSpawn*)node)->GetNumberHarvests() == 0) { LuaSpell* spell = lua_interface->GetCurrentSpell(state); - player->GetZone()->RemoveSpawn(node, true, true, true, true, (spell != nullptr) ? false : true); + player->GetZone()->RemoveSpawn(node, true, true, true, false, (spell != nullptr) ? false : true); } } } diff --git a/source/WorldServer/zoneserver.cpp b/source/WorldServer/zoneserver.cpp index d318cc7..fe9ee83 100644 --- a/source/WorldServer/zoneserver.cpp +++ b/source/WorldServer/zoneserver.cpp @@ -1515,66 +1515,67 @@ void ZoneServer::DeleteSpawns(bool delete_all) { // Prepare a list of entries we’ll need to keep around std::vector> to_keep; - to_keep.reserve(to_process.size()); - - int32 current_time = Timer::GetCurrentTime2(); - MSpawnList.writelock(__FUNCTION__, __LINE__); - for (auto &entry : to_process) { - Spawn* spawn = entry.first; - int32 when = entry.second; + if(to_process.size() > 0) { + to_keep.reserve(to_process.size()); + int32 current_time = Timer::GetCurrentTime2(); + MSpawnList.writelock(__FUNCTION__, __LINE__); + for (auto &entry : to_process) { + Spawn* spawn = entry.first; + int32 when = entry.second; - if (!delete_all && current_time < when) { - to_keep.emplace_back(entry); - continue; - } - - MPendingSpawnRemoval.readlock(__FUNCTION__, __LINE__); - if(!delete_all && m_pendingSpawnRemove.count(spawn->GetID())) { - to_keep.emplace_back(entry); + if (!delete_all && current_time < when) { + to_keep.emplace_back(entry); + continue; + } + + MPendingSpawnRemoval.readlock(__FUNCTION__, __LINE__); + if(!delete_all && m_pendingSpawnRemove.count(spawn->GetID())) { + to_keep.emplace_back(entry); + MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__); + continue; + } MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__); - continue; - } - MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__); - lua_interface->SetLuaUserDataStale(spawn); + lua_interface->SetLuaUserDataStale(spawn); - if (spellProcess) { - spellProcess->RemoveCaster(spawn, true); - } - - if(movementMgr != nullptr) { - movementMgr->RemoveMob((Entity*)spawn); - } - - // delete brain if it has one - if(spawn->IsNPC()) { - NPC* tmpNPC = (NPC*)spawn; - if(tmpNPC->Brain()) - tmpNPC->SetBrain(nullptr); - } - - std::map::iterator sitr = spawn_list.find(spawn->GetID()); - if(sitr != spawn_list.end()) { - spawn_list.erase(sitr); - } - - if(spawn->IsCollector()) { - std::map::iterator subitr = subspawn_list[SUBSPAWN_TYPES::COLLECTOR].find(spawn->GetID()); - if(subitr != subspawn_list[SUBSPAWN_TYPES::COLLECTOR].end()) { - subspawn_list[SUBSPAWN_TYPES::COLLECTOR].erase(subitr); + if (spellProcess) { + spellProcess->RemoveCaster(spawn, true); } - } - - if(spawn->GetPickupItemID()) { - std::map::iterator subitr = subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].find(spawn->GetPickupItemID()); - if(subitr != subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].end() && subitr->second == spawn) { - subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].erase(subitr); + + if(movementMgr != nullptr) { + movementMgr->RemoveMob((Entity*)spawn); } - housing_spawn_map.erase(spawn->GetID()); + + // delete brain if it has one + if(spawn->IsNPC()) { + NPC* tmpNPC = (NPC*)spawn; + if(tmpNPC->Brain()) + tmpNPC->SetBrain(nullptr); + } + + std::map::iterator sitr = spawn_list.find(spawn->GetID()); + if(sitr != spawn_list.end()) { + spawn_list.erase(sitr); + } + + if(spawn->IsCollector()) { + std::map::iterator subitr = subspawn_list[SUBSPAWN_TYPES::COLLECTOR].find(spawn->GetID()); + if(subitr != subspawn_list[SUBSPAWN_TYPES::COLLECTOR].end()) { + subspawn_list[SUBSPAWN_TYPES::COLLECTOR].erase(subitr); + } + } + + if(spawn->GetPickupItemID()) { + std::map::iterator subitr = subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].find(spawn->GetPickupItemID()); + if(subitr != subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].end() && subitr->second == spawn) { + subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].erase(subitr); + } + housing_spawn_map.erase(spawn->GetID()); + } + safe_delete(spawn); } - safe_delete(spawn); + MSpawnList.releasewritelock(__FUNCTION__, __LINE__); } - MSpawnList.releasewritelock(__FUNCTION__, __LINE__); // Add all the kept entries if (!to_keep.empty()) {