From 862da9a55fe94ae70a5bba306139b5eb1bb7f6f7 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 22 Dec 2010 17:55:58 -0800 Subject: [PATCH] Added a counter to NewFiles in Xfers to account for simultaneous object inventory requests, which apparently are happening and may cause race conditions if the file name is removed after the first transfer. --- .../CoreModules/Agent/Xfer/XferModule.cs | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index 57875dac26..c5a6e628bd 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs @@ -40,8 +40,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer private Scene m_scene; private Dictionary Requests = new Dictionary(); private List RequestTime = new List(); - public Dictionary NewFiles = new Dictionary(); - public Dictionary Transfers = new Dictionary(); + private Dictionary NewFiles = new Dictionary(); + private Dictionary Transfers = new Dictionary(); public struct XferRequest @@ -51,6 +51,12 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer public string fileName; public DateTime timeStamp; } + + private class FileData + { + public byte[] Data; + public int Count; + } #region IRegionModule Members @@ -89,21 +95,22 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer lock (NewFiles) { if (NewFiles.ContainsKey(fileName)) - { - NewFiles[fileName] = data; - } + NewFiles[fileName].Count++; else { - NewFiles.Add(fileName, data); + FileData fd = new FileData(); + fd.Count = 1; + fd.Data = data; + NewFiles.Add(fileName, fd); } } - string filename = string.Empty; - if (Requests.ContainsKey(fileName)) - { - RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); - Requests.Remove(fileName); - } + // This should not be here + //if (Requests.ContainsKey(fileName)) + //{ + // RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); + // Requests.Remove(fileName); + //} return true; } @@ -135,6 +142,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer ulong zxferid = RequestTime[0].xferID; remoteClient.SendAbortXferPacket(zxferid); RemoveXferData(zxferid); + RemoveOrDecrement(fileName); } } @@ -142,16 +150,19 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { if (!Transfers.ContainsKey(xferID)) { - byte[] fileData = NewFiles[fileName]; + byte[] fileData = NewFiles[fileName].Data; XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); Transfers.Add(xferID, transaction); - NewFiles.Remove(fileName); if (transaction.StartSend()) { RemoveXferData(xferID); } + + // The transaction for this file is either complete or on its way + RemoveOrDecrement(fileName); + } } else @@ -195,6 +206,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { { RemoveXferData(xferID); + RemoveOrDecrement(dl.FileName); } } else @@ -226,8 +238,6 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer xferItem.DataPointer = 0; // If the abort comes in - if (NewFiles.ContainsKey(xferItem.FileName)) - NewFiles.Remove(xferItem.FileName); if (Requests.ContainsKey(xferItem.FileName)) Requests.Remove(xferItem.FileName); @@ -239,10 +249,26 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { lock (NewFiles) { + if (Transfers.ContainsKey(xferID)) + RemoveOrDecrement(Transfers[xferID].FileName); + RemoveXferData(xferID); } } + private void RemoveOrDecrement(string fileName) + { + // NewFiles must be locked + + if (NewFiles.ContainsKey(fileName)) + { + if (NewFiles[fileName].Count == 1) + NewFiles.Remove(fileName); + else + NewFiles[fileName].Count--; + } + } + #region Nested type: XferDownLoad public class XferDownLoad