diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent')
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs | 122 |
1 files changed, 105 insertions, 17 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index ef7dce8..c5a6e62 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 | |||
40 | private Scene m_scene; | 40 | private Scene m_scene; |
41 | private Dictionary<string, XferRequest> Requests = new Dictionary<string, XferRequest>(); | 41 | private Dictionary<string, XferRequest> Requests = new Dictionary<string, XferRequest>(); |
42 | private List<XferRequest> RequestTime = new List<XferRequest>(); | 42 | private List<XferRequest> RequestTime = new List<XferRequest>(); |
43 | public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>(); | 43 | private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>(); |
44 | public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); | 44 | private Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); |
45 | 45 | ||
46 | 46 | ||
47 | public struct XferRequest | 47 | public struct XferRequest |
@@ -51,6 +51,12 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
51 | public string fileName; | 51 | public string fileName; |
52 | public DateTime timeStamp; | 52 | public DateTime timeStamp; |
53 | } | 53 | } |
54 | |||
55 | private class FileData | ||
56 | { | ||
57 | public byte[] Data; | ||
58 | public int Count; | ||
59 | } | ||
54 | 60 | ||
55 | #region IRegionModule Members | 61 | #region IRegionModule Members |
56 | 62 | ||
@@ -89,20 +95,22 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
89 | lock (NewFiles) | 95 | lock (NewFiles) |
90 | { | 96 | { |
91 | if (NewFiles.ContainsKey(fileName)) | 97 | if (NewFiles.ContainsKey(fileName)) |
92 | { | 98 | NewFiles[fileName].Count++; |
93 | NewFiles[fileName] = data; | ||
94 | } | ||
95 | else | 99 | else |
96 | { | 100 | { |
97 | NewFiles.Add(fileName, data); | 101 | FileData fd = new FileData(); |
102 | fd.Count = 1; | ||
103 | fd.Data = data; | ||
104 | NewFiles.Add(fileName, fd); | ||
98 | } | 105 | } |
99 | } | 106 | } |
100 | 107 | ||
101 | if (Requests.ContainsKey(fileName)) | 108 | // This should not be here |
102 | { | 109 | //if (Requests.ContainsKey(fileName)) |
103 | RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); | 110 | //{ |
104 | Requests.Remove(fileName); | 111 | // RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); |
105 | } | 112 | // Requests.Remove(fileName); |
113 | //} | ||
106 | 114 | ||
107 | return true; | 115 | return true; |
108 | } | 116 | } |
@@ -113,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
113 | { | 121 | { |
114 | client.OnRequestXfer += RequestXfer; | 122 | client.OnRequestXfer += RequestXfer; |
115 | client.OnConfirmXfer += AckPacket; | 123 | client.OnConfirmXfer += AckPacket; |
124 | client.OnAbortXfer += AbortXfer; | ||
116 | } | 125 | } |
117 | 126 | ||
118 | /// <summary> | 127 | /// <summary> |
@@ -125,20 +134,35 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
125 | { | 134 | { |
126 | lock (NewFiles) | 135 | lock (NewFiles) |
127 | { | 136 | { |
137 | if (RequestTime.Count > 0) | ||
138 | { | ||
139 | TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - RequestTime[0].timeStamp.Ticks); | ||
140 | if (ts.TotalSeconds > 30) | ||
141 | { | ||
142 | ulong zxferid = RequestTime[0].xferID; | ||
143 | remoteClient.SendAbortXferPacket(zxferid); | ||
144 | RemoveXferData(zxferid); | ||
145 | RemoveOrDecrement(fileName); | ||
146 | } | ||
147 | } | ||
148 | |||
128 | if (NewFiles.ContainsKey(fileName)) | 149 | if (NewFiles.ContainsKey(fileName)) |
129 | { | 150 | { |
130 | if (!Transfers.ContainsKey(xferID)) | 151 | if (!Transfers.ContainsKey(xferID)) |
131 | { | 152 | { |
132 | byte[] fileData = NewFiles[fileName]; | 153 | byte[] fileData = NewFiles[fileName].Data; |
133 | XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); | 154 | XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); |
134 | 155 | ||
135 | Transfers.Add(xferID, transaction); | 156 | Transfers.Add(xferID, transaction); |
136 | NewFiles.Remove(fileName); | ||
137 | 157 | ||
138 | if (transaction.StartSend()) | 158 | if (transaction.StartSend()) |
139 | { | 159 | { |
140 | Transfers.Remove(xferID); | 160 | RemoveXferData(xferID); |
141 | } | 161 | } |
162 | |||
163 | // The transaction for this file is either complete or on its way | ||
164 | RemoveOrDecrement(fileName); | ||
165 | |||
142 | } | 166 | } |
143 | } | 167 | } |
144 | else | 168 | else |
@@ -150,6 +174,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
150 | { | 174 | { |
151 | Requests.Remove(RequestTime[0].fileName); | 175 | Requests.Remove(RequestTime[0].fileName); |
152 | RequestTime.RemoveAt(0); | 176 | RequestTime.RemoveAt(0); |
177 | // Do we want to abort this here? | ||
178 | //remoteClient.SendAbortXfer(xferID); | ||
153 | } | 179 | } |
154 | } | 180 | } |
155 | 181 | ||
@@ -165,22 +191,84 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
165 | } | 191 | } |
166 | 192 | ||
167 | } | 193 | } |
194 | |||
168 | } | 195 | } |
169 | } | 196 | } |
170 | 197 | ||
171 | public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) | 198 | public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) |
172 | { | 199 | { |
173 | if (Transfers.ContainsKey(xferID)) | 200 | lock (NewFiles) // This is actually to lock Transfers |
174 | { | 201 | { |
175 | if (Transfers[xferID].AckPacket(packet)) | 202 | if (Transfers.ContainsKey(xferID)) |
176 | { | 203 | { |
204 | XferDownLoad dl = Transfers[xferID]; | ||
205 | if (Transfers[xferID].AckPacket(packet)) | ||
206 | { | ||
207 | { | ||
208 | RemoveXferData(xferID); | ||
209 | RemoveOrDecrement(dl.FileName); | ||
210 | } | ||
211 | } | ||
212 | else | ||
177 | { | 213 | { |
178 | Transfers.Remove(xferID); | 214 | |
215 | if (Requests.ContainsKey(dl.FileName)) | ||
216 | { | ||
217 | // | ||
218 | XferRequest req = Requests[dl.FileName]; | ||
219 | req.timeStamp = DateTime.UtcNow; | ||
220 | Requests[dl.FileName] = req; | ||
221 | } | ||
179 | } | 222 | } |
180 | } | 223 | } |
181 | } | 224 | } |
182 | } | 225 | } |
183 | 226 | ||
227 | private void RemoveXferData(ulong xferID) | ||
228 | { | ||
229 | // NewFiles must be locked! | ||
230 | if (Transfers.ContainsKey(xferID)) | ||
231 | { | ||
232 | // Qualifier distinguishes between the OpenMetaverse version and the nested class | ||
233 | |||
234 | XferModule.XferDownLoad xferItem = Transfers[xferID]; | ||
235 | //string filename = xferItem.FileName; | ||
236 | Transfers.Remove(xferID); | ||
237 | xferItem.Data = new byte[0]; // Clear the data | ||
238 | xferItem.DataPointer = 0; | ||
239 | |||
240 | // If the abort comes in | ||
241 | |||
242 | if (Requests.ContainsKey(xferItem.FileName)) | ||
243 | Requests.Remove(xferItem.FileName); | ||
244 | |||
245 | } | ||
246 | } | ||
247 | |||
248 | public void AbortXfer(IClientAPI remoteClient, ulong xferID) | ||
249 | { | ||
250 | lock (NewFiles) | ||
251 | { | ||
252 | if (Transfers.ContainsKey(xferID)) | ||
253 | RemoveOrDecrement(Transfers[xferID].FileName); | ||
254 | |||
255 | RemoveXferData(xferID); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | private void RemoveOrDecrement(string fileName) | ||
260 | { | ||
261 | // NewFiles must be locked | ||
262 | |||
263 | if (NewFiles.ContainsKey(fileName)) | ||
264 | { | ||
265 | if (NewFiles[fileName].Count == 1) | ||
266 | NewFiles.Remove(fileName); | ||
267 | else | ||
268 | NewFiles[fileName].Count--; | ||
269 | } | ||
270 | } | ||
271 | |||
184 | #region Nested type: XferDownLoad | 272 | #region Nested type: XferDownLoad |
185 | 273 | ||
186 | public class XferDownLoad | 274 | public class XferDownLoad |