diff options
Merge branch 'master' of brain.opensimulator.org:/var/git/opensim
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs | 122 |
1 files changed, 59 insertions, 63 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index 1b6401a..56123a5 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs | |||
@@ -50,8 +50,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 51 | ||
52 | private object timeTickLock = new object(); | 52 | private object timeTickLock = new object(); |
53 | private double lastTimeTick = 0.0; | 53 | private int lastTimeTick = 0; |
54 | private double lastFilesExpire = 0.0; | 54 | private int lastFilesExpire = 0; |
55 | private bool inTimeTick = false; | 55 | private bool inTimeTick = false; |
56 | 56 | ||
57 | public struct XferRequest | 57 | public struct XferRequest |
@@ -66,15 +66,15 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
66 | { | 66 | { |
67 | public byte[] Data; | 67 | public byte[] Data; |
68 | public int refsCount; | 68 | public int refsCount; |
69 | public double timeStampMS; | 69 | public int timeStampMS; |
70 | } | 70 | } |
71 | 71 | ||
72 | #region INonSharedRegionModule Members | 72 | #region INonSharedRegionModule Members |
73 | 73 | ||
74 | public void Initialise(IConfigSource config) | 74 | public void Initialise(IConfigSource config) |
75 | { | 75 | { |
76 | lastTimeTick = Util.GetTimeStampMS() + 30000.0; | 76 | lastTimeTick = (int)Util.GetTimeStampMS() + 30000; |
77 | lastFilesExpire = lastTimeTick + 180000.0; | 77 | lastFilesExpire = lastTimeTick + 180000; |
78 | } | 78 | } |
79 | 79 | ||
80 | public void AddRegion(Scene scene) | 80 | public void AddRegion(Scene scene) |
@@ -121,10 +121,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
121 | { | 121 | { |
122 | if(!inTimeTick) | 122 | if(!inTimeTick) |
123 | { | 123 | { |
124 | double now = Util.GetTimeStampMS(); | 124 | int now = (int)Util.GetTimeStampMS(); |
125 | if(now - lastTimeTick > 1750.0) | 125 | if(now - lastTimeTick > 750) |
126 | { | 126 | { |
127 | |||
128 | if(Transfers.Count == 0 && NewFiles.Count == 0) | 127 | if(Transfers.Count == 0 && NewFiles.Count == 0) |
129 | lastTimeTick = now; | 128 | lastTimeTick = now; |
130 | else | 129 | else |
@@ -163,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
163 | { | 162 | { |
164 | lock (NewFiles) | 163 | lock (NewFiles) |
165 | { | 164 | { |
166 | double now = Util.GetTimeStampMS(); | 165 | int now = (int)Util.GetTimeStampMS(); |
167 | if (NewFiles.ContainsKey(fileName)) | 166 | if (NewFiles.ContainsKey(fileName)) |
168 | { | 167 | { |
169 | NewFiles[fileName].refsCount++; | 168 | NewFiles[fileName].refsCount++; |
@@ -183,18 +182,18 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
183 | } | 182 | } |
184 | 183 | ||
185 | #endregion | 184 | #endregion |
186 | public void expireFiles(double now) | 185 | public void expireFiles(int now) |
187 | { | 186 | { |
188 | lock (NewFiles) | 187 | lock (NewFiles) |
189 | { | 188 | { |
190 | // hopefully we will not have many files so nasty code will do it | 189 | // hopefully we will not have many files so nasty code will do it |
191 | if(now - lastFilesExpire > 120000.0) | 190 | if(now - lastFilesExpire > 120000) |
192 | { | 191 | { |
193 | lastFilesExpire = now; | 192 | lastFilesExpire = now; |
194 | List<string> expires = new List<string>(); | 193 | List<string> expires = new List<string>(); |
195 | foreach(string fname in NewFiles.Keys) | 194 | foreach(string fname in NewFiles.Keys) |
196 | { | 195 | { |
197 | if(NewFiles[fname].refsCount == 0 && now - NewFiles[fname].timeStampMS > 120000.0) | 196 | if(NewFiles[fname].refsCount == 0 && now - NewFiles[fname].timeStampMS > 120000) |
198 | expires.Add(fname); | 197 | expires.Add(fname); |
199 | } | 198 | } |
200 | foreach(string fname in expires) | 199 | foreach(string fname in expires) |
@@ -230,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
230 | } | 229 | } |
231 | } | 230 | } |
232 | 231 | ||
233 | public void transfersTimeTick(double now) | 232 | public void transfersTimeTick(int now) |
234 | { | 233 | { |
235 | XferDownLoad[] xfrs; | 234 | XferDownLoad[] xfrs; |
236 | lock(Transfers) | 235 | lock(Transfers) |
@@ -241,6 +240,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
241 | xfrs = new XferDownLoad[Transfers.Count]; | 240 | xfrs = new XferDownLoad[Transfers.Count]; |
242 | Transfers.Values.CopyTo(xfrs,0); | 241 | Transfers.Values.CopyTo(xfrs,0); |
243 | } | 242 | } |
243 | |||
244 | foreach(XferDownLoad xfr in xfrs) | 244 | foreach(XferDownLoad xfr in xfrs) |
245 | { | 245 | { |
246 | if(xfr.checkTime(now)) | 246 | if(xfr.checkTime(now)) |
@@ -272,14 +272,15 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
272 | if (!Transfers.ContainsKey(xferID)) | 272 | if (!Transfers.ContainsKey(xferID)) |
273 | { | 273 | { |
274 | byte[] fileData = NewFiles[fileName].Data; | 274 | byte[] fileData = NewFiles[fileName].Data; |
275 | int burstSize = remoteClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset) >> 11; | 275 | int burstSize = remoteClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Task) >> 10; |
276 | if(Transfers.Count > 1) | 276 | burstSize *= remoteClient.PingTimeMS; |
277 | burstSize /= Transfers.Count; | 277 | burstSize >>= 10; // ping is ms, 1 round trip |
278 | if(burstSize > 32) | ||
279 | burstSize = 32; | ||
278 | XferDownLoad transaction = | 280 | XferDownLoad transaction = |
279 | new XferDownLoad(fileName, fileData, xferID, remoteClient, burstSize); | 281 | new XferDownLoad(fileName, fileData, xferID, remoteClient, burstSize); |
280 | 282 | ||
281 | Transfers.Add(xferID, transaction); | 283 | Transfers.Add(xferID, transaction); |
282 | |||
283 | transaction.StartSend(); | 284 | transaction.StartSend(); |
284 | 285 | ||
285 | // The transaction for this file is on its way | 286 | // The transaction for this file is on its way |
@@ -320,27 +321,27 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
320 | 321 | ||
321 | public class XferDownLoad | 322 | public class XferDownLoad |
322 | { | 323 | { |
323 | public IClientAPI Client; | 324 | public IClientAPI remoteClient; |
324 | public byte[] Data = new byte[0]; | 325 | public byte[] Data = new byte[0]; |
325 | public string FileName = String.Empty; | 326 | public string FileName = String.Empty; |
326 | public ulong XferID = 0; | 327 | public ulong XferID = 0; |
327 | public bool isDeleted = false; | 328 | public bool isDeleted = false; |
328 | 329 | ||
329 | private object myLock = new object(); | 330 | private object myLock = new object(); |
330 | private double lastsendTimeMS; | 331 | private int lastACKTimeMS; |
331 | private int LastPacket; | 332 | private int LastPacket; |
332 | private int lastBytes; | 333 | private int lastBytes; |
333 | private int lastSentPacket; | 334 | private int lastSentPacket; |
334 | private int lastAckPacket; | 335 | private int lastAckPacket; |
335 | private int burstSize; | 336 | private int burstSize; // additional packets, so can be zero |
336 | private int retries = 0; | 337 | private int retries; |
337 | 338 | ||
338 | public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client, int burstsz) | 339 | public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client, int burstsz) |
339 | { | 340 | { |
340 | FileName = fileName; | 341 | FileName = fileName; |
341 | Data = data; | 342 | Data = data; |
342 | XferID = xferID; | 343 | XferID = xferID; |
343 | Client = client; | 344 | remoteClient = client; |
344 | burstSize = burstsz; | 345 | burstSize = burstsz; |
345 | } | 346 | } |
346 | 347 | ||
@@ -352,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
352 | { | 353 | { |
353 | if(!isDeleted) | 354 | if(!isDeleted) |
354 | { | 355 | { |
355 | Data = new byte[0]; | 356 | Data = null; |
356 | isDeleted = true; | 357 | isDeleted = true; |
357 | } | 358 | } |
358 | } | 359 | } |
@@ -381,30 +382,29 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
381 | lastBytes = 1024; | 382 | lastBytes = 1024; |
382 | LastPacket--; | 383 | LastPacket--; |
383 | } | 384 | } |
384 | |||
385 | } | 385 | } |
386 | 386 | ||
387 | lastAckPacket = -1; | 387 | lastAckPacket = -1; |
388 | lastSentPacket = -1; | 388 | lastSentPacket = -1; |
389 | retries = 0; | ||
389 | 390 | ||
390 | double now = Util.GetTimeStampMS(); | 391 | SendBurst(); |
391 | |||
392 | SendBurst(now); | ||
393 | return; | 392 | return; |
394 | } | 393 | } |
395 | } | 394 | } |
396 | 395 | ||
397 | private void SendBurst(double now) | 396 | private void SendBurst() |
398 | { | 397 | { |
399 | int start = lastAckPacket + 1; | 398 | int start = lastAckPacket + 1; |
400 | int end = start + burstSize; | 399 | int end = start + burstSize; |
401 | if (end > LastPacket) | 400 | if (end > LastPacket) |
402 | end = LastPacket; | 401 | end = LastPacket; |
403 | while(start <= end) | 402 | while (start <= end) |
404 | SendPacket(start++ , now); | 403 | SendPacket(start++); |
404 | lastACKTimeMS = (int)Util.GetTimeStampMS() + 1000; // reset timeout with some slack for queues delays | ||
405 | } | 405 | } |
406 | 406 | ||
407 | private void SendPacket(int pkt, double now) | 407 | private void SendPacket(int pkt) |
408 | { | 408 | { |
409 | if(pkt > LastPacket) | 409 | if(pkt > LastPacket) |
410 | return; | 410 | return; |
@@ -422,23 +422,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
422 | pktid = (uint)pkt; | 422 | pktid = (uint)pkt; |
423 | } | 423 | } |
424 | 424 | ||
425 | byte[] transferData; | 425 | remoteClient.SendXferPacket(XferID, pktid, Data, pkt << 10, pktsize, true); |
426 | if(pkt == 0) | ||
427 | { | ||
428 | transferData = new byte[pktsize + 4]; | ||
429 | Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); | ||
430 | Array.Copy(Data, 0, transferData, 4, pktsize); | ||
431 | } | ||
432 | else | ||
433 | { | ||
434 | transferData = new byte[pktsize]; | ||
435 | Array.Copy(Data, pkt << 10, transferData, 0, pktsize); | ||
436 | } | ||
437 | |||
438 | Client.SendXferPacket(XferID, pktid, transferData, false); | ||
439 | 426 | ||
440 | lastSentPacket = pkt; | 427 | lastSentPacket = pkt; |
441 | lastsendTimeMS = now; | ||
442 | } | 428 | } |
443 | 429 | ||
444 | /// <summary> | 430 | /// <summary> |
@@ -453,39 +439,49 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer | |||
453 | if(isDeleted) | 439 | if(isDeleted) |
454 | return true; | 440 | return true; |
455 | 441 | ||
456 | packet &= 0x7fffffff; | 442 | packet &= 0x7fffffff; |
457 | if(lastAckPacket < packet) | 443 | if (lastAckPacket < packet) |
458 | lastAckPacket = (int)packet; | 444 | lastAckPacket = (int)packet; |
459 | 445 | else if (lastAckPacket == LastPacket) | |
460 | if(lastAckPacket == LastPacket) | ||
461 | { | 446 | { |
462 | done(); | 447 | done(); |
463 | return true; | 448 | return true; |
464 | } | 449 | } |
465 | double now = Util.GetTimeStampMS(); | 450 | |
466 | SendPacket(lastSentPacket + 1, now); | 451 | lastACKTimeMS = (int)Util.GetTimeStampMS(); |
452 | retries = 0; | ||
453 | SendPacket(lastSentPacket + 1); | ||
467 | return false; | 454 | return false; |
468 | } | 455 | } |
469 | } | 456 | } |
470 | 457 | ||
471 | public bool checkTime(double now) | 458 | public bool checkTime(int now) |
472 | { | 459 | { |
473 | if(Monitor.TryEnter(myLock)) | 460 | if (Monitor.TryEnter(myLock)) |
474 | { | 461 | { |
475 | if(!isDeleted) | 462 | if (!isDeleted) |
476 | { | 463 | { |
477 | double timeMS = now - lastsendTimeMS; | 464 | int timeMS = now - lastACKTimeMS; |
478 | if(timeMS > 60000.0) | 465 | int tout = 5 * remoteClient.PingTimeMS; |
479 | done(); | 466 | if (tout < 1000) |
480 | else if(timeMS > 3500.0 && retries++ < 3) | 467 | tout = 1000; |
468 | else if(tout > 10000) | ||
469 | tout = 10000; | ||
470 | |||
471 | if (timeMS > tout) | ||
481 | { | 472 | { |
482 | burstSize >>= 1; | 473 | if (++retries > 4) |
483 | SendBurst(now); | 474 | done(); |
475 | else | ||
476 | { | ||
477 | burstSize = lastSentPacket - lastAckPacket; | ||
478 | SendBurst(); | ||
479 | } | ||
484 | } | 480 | } |
485 | } | 481 | } |
486 | 482 | bool isdel = isDeleted; | |
487 | Monitor.Exit(myLock); | 483 | Monitor.Exit(myLock); |
488 | return isDeleted; | 484 | return isdel; |
489 | } | 485 | } |
490 | return false; | 486 | return false; |
491 | } | 487 | } |