diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 4a0b0c6dd1..626ebb5939 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1546,41 +1546,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
kill.Header.Reliable = true;
kill.Header.Zerocoded = true;
- lock (m_killRecord)
+ if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
{
- if (localIDs.Count == 1)
+ OutPacket(kill, ThrottleOutPacketType.State);
+ }
+ else
+ {
+ // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
+ // condition where a kill can be processed before an out-of-date update for the same object.
+ // ProcessEntityUpdates() also takes the m_killRecord lock.
+ lock (m_killRecord)
{
- if (m_scene.GetScenePresence(localIDs[0]) != null)
- {
- OutPacket(kill, ThrottleOutPacketType.State);
- return;
- }
- m_killRecord.Add(localIDs[0]);
- }
- else
- {
- lock (m_entityUpdates.SyncRoot)
- {
- foreach (uint localID in localIDs)
- m_killRecord.Add(localID);
- }
+ foreach (uint localID in localIDs)
+ m_killRecord.Add(localID);
+
+ // The throttle queue used here must match that being used for updates. Otherwise, there is a
+ // chance that a kill packet put on a separate queue will be sent to the client before an existing
+ // update packet on another queue. Receiving updates after kills results in unowned and undeletable
+ // scene objects in a viewer until that viewer is relogged in.
+ OutPacket(kill, ThrottleOutPacketType.Task);
}
}
-
- // The throttle queue used here must match that being used for
- // updates. Otherwise, there is a chance that a kill packet put
- // on a separate queue will be sent to the client before an
- // existing update packet on another queue. Receiving updates
- // after kills results in unowned and undeletable
- // scene objects in a viewer until that viewer is relogged in.
- OutPacket(kill, ThrottleOutPacketType.Task);
}
///
/// Send information about the items contained in a folder to the client.
- ///
- /// XXX This method needs some refactoring loving
///
+ ///
+ /// XXX This method needs some refactoring loving
+ ///
/// The owner of the folder
/// The id of the folder
/// The items contained in the folder identified by folderID