Browse Source

Additional deadlocks fixed in ProcessMovement

Command_Hail needs to lock MSpawnList when it triggers ProcessMovement.  When we are doing SpawnProcess however, we already have MSpawnList locked, no need to lock again.
Image 4 years ago
parent
commit
4c33e979a0

+ 3 - 3
EQ2/source/WorldServer/Spawn.cpp

@@ -1783,14 +1783,14 @@ void Spawn::MoveToLocation(Spawn* spawn, float distance, bool immediate){
 	AddRunningLocation(spawn->GetX(), spawn->GetY(), spawn->GetZ(), GetSpeed(), distance);
 }
 
-void Spawn::ProcessMovement(){
+void Spawn::ProcessMovement(bool isSpawnListLocked){
 	if(IsPlayer()){
 		//Check if player is riding a boat, if so update pos (boat's current location + XYZ offsets)
 		Player* player = ((Player*)this);
 		int32 boat_id = player->GetBoatSpawn();
 		Spawn* boat = 0;
 		if(boat_id > 0)
-			boat = GetZone()->GetSpawnByID(boat_id);
+			boat = GetZone()->GetSpawnByID(boat_id, isSpawnListLocked);
 		if(boat){
 			SetX(boat->GetX() + player->GetBoatX());
 			SetY(boat->GetY() + player->GetBoatY());
@@ -1803,7 +1803,7 @@ void Spawn::ProcessMovement(){
 		return;
 
 	MMovementLoop.lock();
-	Spawn* followTarget = GetZone()->GetSpawnByID(m_followTarget);
+	Spawn* followTarget = GetZone()->GetSpawnByID(m_followTarget, isSpawnListLocked);
 	if (!followTarget && m_followTarget > 0)
 		m_followTarget = 0;
 	if (following && followTarget) {

+ 1 - 1
EQ2/source/WorldServer/Spawn.h

@@ -847,7 +847,7 @@ public:
 
 	void	MoveToLocation(Spawn* spawn, float distance, bool immediate = true);
 	void	AddMovementLocation(float x, float y, float z, float speed, int16 delay, const char* lua_function);
-	void	ProcessMovement();
+	void	ProcessMovement(bool isSpawnListLocked=false);
 	void	ResetMovement();
 	bool	IsRunning();
 	void	CalculateRunningLocation(bool stop = false);

+ 1 - 20
EQ2/source/WorldServer/zoneserver.cpp

@@ -1522,7 +1522,7 @@ bool ZoneServer::SpawnProcess(){
 			if (spawn) {
 				// Process spawn movement
 				if (movement) {
-					spawn->ProcessMovement();
+					spawn->ProcessMovement(true);
 					// update last_movement_update for all spawns (used for time_step)
 					spawn->last_movement_update = Timer::GetCurrentTime2();
 				}
@@ -3196,25 +3196,6 @@ void ZoneServer::RemoveMovementNPC(Spawn* spawn){
 		remove_movement_spawns.Add(spawn->GetID());
 }
 
-void ZoneServer::ProcessMovement(){	
-	Spawn* spawn = 0;
-	MutexMap<int32, int32>::iterator itr = movement_spawns.begin();
-	while(itr.Next()){
-		spawn = GetSpawnByID(itr->first);
-		if(spawn) {
-			if(spawn->IsNPC() && !spawn->MovementInterrupted())
-				spawn->ProcessMovement();
-		}
-		else
-			movement_spawns.erase(itr->first);
-	}
-	MutexList<int32>::iterator remove_itr = remove_movement_spawns.begin();
-	while(remove_itr.Next()){
-		movement_spawns.erase(remove_itr->value);
-	}
-	remove_movement_spawns.clear();
-}
-
 void ZoneServer::PlayFlavor(Client* client, Spawn* spawn, const char* mp3, const char* text, const char* emote, int32 key1, int32 key2, int8 language){
 	if(!client || !spawn)
 		return;

+ 0 - 1
EQ2/source/WorldServer/zoneserver.h

@@ -645,7 +645,6 @@ private:
 	void	CheckSpawnScriptTimers();																			// never used outside zone server
 	void	CheckHeadingTimers();																				// never used outside zone server
 	void	RemoveHeadingTimer(Spawn* spawn);																	// never used outside zone server
-	void	ProcessMovement();																					// never used outside zone server
 	void	PrepareSpawnID(Player* player, Spawn* spawn);														// never used outside zone server
 	void	RemoveMovementNPC(Spawn* spawn);																	// never used outside zone server
 	bool	CheckNPCAttacks(NPC* npc, Spawn* victim, Client* client = 0);										// never used outside zone server