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.

viewer-2-initial-appearance
Diva Canto 2010-12-22 17:55:58 -08:00
parent f29675bf87
commit 862da9a55f
1 changed files with 42 additions and 16 deletions

View File

@ -40,8 +40,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
private Scene m_scene; private Scene m_scene;
private Dictionary<string, XferRequest> Requests = new Dictionary<string, XferRequest>(); private Dictionary<string, XferRequest> Requests = new Dictionary<string, XferRequest>();
private List<XferRequest> RequestTime = new List<XferRequest>(); private List<XferRequest> RequestTime = new List<XferRequest>();
public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>(); private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>();
public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); private Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
public struct XferRequest public struct XferRequest
@ -52,6 +52,12 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
public DateTime timeStamp; public DateTime timeStamp;
} }
private class FileData
{
public byte[] Data;
public int Count;
}
#region IRegionModule Members #region IRegionModule Members
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
@ -89,21 +95,22 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
lock (NewFiles) lock (NewFiles)
{ {
if (NewFiles.ContainsKey(fileName)) if (NewFiles.ContainsKey(fileName))
{ NewFiles[fileName].Count++;
NewFiles[fileName] = data;
}
else 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)) // This should not be here
{ //if (Requests.ContainsKey(fileName))
RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); //{
Requests.Remove(fileName); // RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName);
} // Requests.Remove(fileName);
//}
return true; return true;
} }
@ -135,6 +142,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
ulong zxferid = RequestTime[0].xferID; ulong zxferid = RequestTime[0].xferID;
remoteClient.SendAbortXferPacket(zxferid); remoteClient.SendAbortXferPacket(zxferid);
RemoveXferData(zxferid); RemoveXferData(zxferid);
RemoveOrDecrement(fileName);
} }
} }
@ -142,16 +150,19 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{ {
if (!Transfers.ContainsKey(xferID)) if (!Transfers.ContainsKey(xferID))
{ {
byte[] fileData = NewFiles[fileName]; byte[] fileData = NewFiles[fileName].Data;
XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
Transfers.Add(xferID, transaction); Transfers.Add(xferID, transaction);
NewFiles.Remove(fileName);
if (transaction.StartSend()) if (transaction.StartSend())
{ {
RemoveXferData(xferID); RemoveXferData(xferID);
} }
// The transaction for this file is either complete or on its way
RemoveOrDecrement(fileName);
} }
} }
else else
@ -195,6 +206,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{ {
{ {
RemoveXferData(xferID); RemoveXferData(xferID);
RemoveOrDecrement(dl.FileName);
} }
} }
else else
@ -226,8 +238,6 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
xferItem.DataPointer = 0; xferItem.DataPointer = 0;
// If the abort comes in // If the abort comes in
if (NewFiles.ContainsKey(xferItem.FileName))
NewFiles.Remove(xferItem.FileName);
if (Requests.ContainsKey(xferItem.FileName)) if (Requests.ContainsKey(xferItem.FileName))
Requests.Remove(xferItem.FileName); Requests.Remove(xferItem.FileName);
@ -239,10 +249,26 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{ {
lock (NewFiles) lock (NewFiles)
{ {
if (Transfers.ContainsKey(xferID))
RemoveOrDecrement(Transfers[xferID].FileName);
RemoveXferData(xferID); 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 #region Nested type: XferDownLoad
public class XferDownLoad public class XferDownLoad