aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-11-11 22:37:57 +0000
committerJustin Clark-Casey (justincc)2011-11-11 22:37:57 +0000
commitce8441132e43dc8e3579f413daf914d48b8f115e (patch)
treeb214c7999eb4f28389bc0e5963c05561d6734af1 /OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
parentremove unncessary IClientAPI parameter from SP.SendSitResponse() (diff)
downloadopensim-SC_OLD-ce8441132e43dc8e3579f413daf914d48b8f115e.zip
opensim-SC_OLD-ce8441132e43dc8e3579f413daf914d48b8f115e.tar.gz
opensim-SC_OLD-ce8441132e43dc8e3579f413daf914d48b8f115e.tar.bz2
opensim-SC_OLD-ce8441132e43dc8e3579f413daf914d48b8f115e.tar.xz
Restore sending of OutPacket() for object kills removed in commit c7dd7b1.
OutPacket() must be called within the m_killRecord lock. Otherwise the following event sequence is possible 1) LLClientView.ProcessEntityUpdates() passes the kill record check for a particular part suspends before OutPacket() 2) Another thread calls LLClientView.SendKillObject() to delete the same part and modifies the kill record 3) The same thread places the kill packet on the Task queue. 4) The earlier thread resumes and places the update packet on the Task queue after the kill packet. This results in a ghost part in the sim that only goes away after client relog. This commit also removes the unnecessary m_entityUpdates.SyncRoot locking in SendKillObject.
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs46
1 files changed, 20 insertions, 26 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 4a0b0c6..626ebb5 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
1546 kill.Header.Reliable = true; 1546 kill.Header.Reliable = true;
1547 kill.Header.Zerocoded = true; 1547 kill.Header.Zerocoded = true;
1548 1548
1549 lock (m_killRecord) 1549 if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null)
1550 { 1550 {
1551 if (localIDs.Count == 1) 1551 OutPacket(kill, ThrottleOutPacketType.State);
1552 { 1552 }
1553 if (m_scene.GetScenePresence(localIDs[0]) != null) 1553 else
1554 { 1554 {
1555 OutPacket(kill, ThrottleOutPacketType.State); 1555 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1556 return; 1556 // condition where a kill can be processed before an out-of-date update for the same object.
1557 } 1557 // ProcessEntityUpdates() also takes the m_killRecord lock.
1558 m_killRecord.Add(localIDs[0]); 1558 lock (m_killRecord)
1559 }
1560 else
1561 { 1559 {
1562 lock (m_entityUpdates.SyncRoot) 1560 foreach (uint localID in localIDs)
1563 { 1561 m_killRecord.Add(localID);
1564 foreach (uint localID in localIDs) 1562
1565 m_killRecord.Add(localID); 1563 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1566 } 1564 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1565 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1566 // scene objects in a viewer until that viewer is relogged in.
1567 OutPacket(kill, ThrottleOutPacketType.Task);
1567 } 1568 }
1568 } 1569 }
1569
1570 // The throttle queue used here must match that being used for
1571 // updates. Otherwise, there is a chance that a kill packet put
1572 // on a separate queue will be sent to the client before an
1573 // existing update packet on another queue. Receiving updates
1574 // after kills results in unowned and undeletable
1575 // scene objects in a viewer until that viewer is relogged in.
1576 OutPacket(kill, ThrottleOutPacketType.Task);
1577 } 1570 }
1578 1571
1579 /// <summary> 1572 /// <summary>
1580 /// Send information about the items contained in a folder to the client. 1573 /// Send information about the items contained in a folder to the client.
1581 ///
1582 /// XXX This method needs some refactoring loving
1583 /// </summary> 1574 /// </summary>
1575 /// <remarks>
1576 /// XXX This method needs some refactoring loving
1577 /// </remarks>
1584 /// <param name="ownerID">The owner of the folder</param> 1578 /// <param name="ownerID">The owner of the folder</param>
1585 /// <param name="folderID">The id of the folder</param> 1579 /// <param name="folderID">The id of the folder</param>
1586 /// <param name="items">The items contained in the folder identified by folderID</param> 1580 /// <param name="items">The items contained in the folder identified by folderID</param>