limiting spawn list write lock further

This commit is contained in:
Emagi 2025-07-30 19:15:47 -04:00
parent 8f47a27b1d
commit 9ef48d3bab
2 changed files with 54 additions and 53 deletions

View File

@ -4707,7 +4707,7 @@ int EQ2Emu_lua_Harvest(lua_State* state) {
((GroundSpawn*)node)->ProcessHarvest(client); ((GroundSpawn*)node)->ProcessHarvest(client);
if (((GroundSpawn*)node)->GetNumberHarvests() == 0) { if (((GroundSpawn*)node)->GetNumberHarvests() == 0) {
LuaSpell* spell = lua_interface->GetCurrentSpell(state); 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);
} }
} }
} }

View File

@ -1515,66 +1515,67 @@ void ZoneServer::DeleteSpawns(bool delete_all) {
// Prepare a list of entries well need to keep around // Prepare a list of entries well need to keep around
std::vector<std::pair<Spawn*,int32>> to_keep; std::vector<std::pair<Spawn*,int32>> to_keep;
to_keep.reserve(to_process.size()); 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;
int32 current_time = Timer::GetCurrentTime2(); if (!delete_all && current_time < when) {
MSpawnList.writelock(__FUNCTION__, __LINE__); to_keep.emplace_back(entry);
for (auto &entry : to_process) { continue;
Spawn* spawn = entry.first; }
int32 when = entry.second;
if (!delete_all && current_time < when) { MPendingSpawnRemoval.readlock(__FUNCTION__, __LINE__);
to_keep.emplace_back(entry); if(!delete_all && m_pendingSpawnRemove.count(spawn->GetID())) {
continue; to_keep.emplace_back(entry);
} MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__);
continue;
MPendingSpawnRemoval.readlock(__FUNCTION__, __LINE__); }
if(!delete_all && m_pendingSpawnRemove.count(spawn->GetID())) {
to_keep.emplace_back(entry);
MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__); MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__);
continue;
}
MPendingSpawnRemoval.releasereadlock(__FUNCTION__, __LINE__);
lua_interface->SetLuaUserDataStale(spawn); lua_interface->SetLuaUserDataStale(spawn);
if (spellProcess) { if (spellProcess) {
spellProcess->RemoveCaster(spawn, true); 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<int32, Spawn*>::iterator sitr = spawn_list.find(spawn->GetID());
if(sitr != spawn_list.end()) {
spawn_list.erase(sitr);
}
if(spawn->IsCollector()) {
std::map<int32, Spawn*>::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()) { if(movementMgr != nullptr) {
std::map<int32, Spawn*>::iterator subitr = subspawn_list[SUBSPAWN_TYPES::HOUSE_ITEM_SPAWN].find(spawn->GetPickupItemID()); movementMgr->RemoveMob((Entity*)spawn);
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());
// delete brain if it has one
if(spawn->IsNPC()) {
NPC* tmpNPC = (NPC*)spawn;
if(tmpNPC->Brain())
tmpNPC->SetBrain(nullptr);
}
std::map<int32, Spawn*>::iterator sitr = spawn_list.find(spawn->GetID());
if(sitr != spawn_list.end()) {
spawn_list.erase(sitr);
}
if(spawn->IsCollector()) {
std::map<int32, Spawn*>::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<int32, Spawn*>::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 // Add all the kept entries
if (!to_keep.empty()) { if (!to_keep.empty()) {