aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/Cache/AssetCache.cs
diff options
context:
space:
mode:
authorMW2008-02-27 16:20:45 +0000
committerMW2008-02-27 16:20:45 +0000
commitaac7c1dda57bf237abba4dd02bc1a25422d03a35 (patch)
tree5835b88a41ccf83949921bb489d9766db4a547ec /OpenSim/Framework/Communications/Cache/AssetCache.cs
parentUpdate svn properties. (diff)
downloadopensim-SC-aac7c1dda57bf237abba4dd02bc1a25422d03a35.zip
opensim-SC-aac7c1dda57bf237abba4dd02bc1a25422d03a35.tar.gz
opensim-SC-aac7c1dda57bf237abba4dd02bc1a25422d03a35.tar.bz2
opensim-SC-aac7c1dda57bf237abba4dd02bc1a25422d03a35.tar.xz
another attempt at fixing asset lockups
Diffstat (limited to 'OpenSim/Framework/Communications/Cache/AssetCache.cs')
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs471
1 files changed, 247 insertions, 224 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index 3bd8f5b..061b857 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -69,12 +69,12 @@ namespace OpenSim.Framework.Communications.Cache
69 /// 69 ///
70 /// Assets requests which are waiting for asset server data. This includes texture requests 70 /// Assets requests which are waiting for asset server data. This includes texture requests
71 /// </summary> 71 /// </summary>
72 private Dictionary<LLUUID, AssetRequest> RequestedAssets; 72 private Dictionary<LLUUID, AssetRequest> RequestedAssets;
73 73
74 /// <summary> 74 /// <summary>
75 /// Asset requests with data which are ready to be sent back to requesters. This includes textures. 75 /// Asset requests with data which are ready to be sent back to requesters. This includes textures.
76 /// </summary> 76 /// </summary>
77 private List<AssetRequest> AssetRequests; 77 private List<AssetRequest> AssetRequests;
78 78
79 79
80 /// <summary> 80 /// <summary>
@@ -94,8 +94,8 @@ namespace OpenSim.Framework.Communications.Cache
94 m_log.InfoFormat("Assets:{0} Textures:{1} AssetRequests:{2} RequestedAssets:{3} RequestLists:{4}", 94 m_log.InfoFormat("Assets:{0} Textures:{1} AssetRequests:{2} RequestedAssets:{3} RequestLists:{4}",
95 Assets.Count, 95 Assets.Count,
96 Textures.Count, 96 Textures.Count,
97 AssetRequests.Count, 97 AssetRequests.Count,
98 RequestedAssets.Count, 98 RequestedAssets.Count,
99 RequestLists.Count); 99 RequestLists.Count);
100 100
101 int temporaryImages = 0; 101 int temporaryImages = 0;
@@ -150,9 +150,9 @@ namespace OpenSim.Framework.Communications.Cache
150 { 150 {
151 Assets = new Dictionary<LLUUID, AssetInfo>(); 151 Assets = new Dictionary<LLUUID, AssetInfo>();
152 Textures = new Dictionary<LLUUID, TextureImage>(); 152 Textures = new Dictionary<LLUUID, TextureImage>();
153 AssetRequests = new List<AssetRequest>(); 153 AssetRequests = new List<AssetRequest>();
154 154
155 RequestedAssets = new Dictionary<LLUUID, AssetRequest>(); 155 RequestedAssets = new Dictionary<LLUUID, AssetRequest>();
156 RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); 156 RequestLists = new Dictionary<LLUUID, AssetRequestsList>();
157 } 157 }
158 158
@@ -168,32 +168,32 @@ namespace OpenSim.Framework.Communications.Cache
168 m_assetServer = assetServer; 168 m_assetServer = assetServer;
169 m_assetServer.SetReceiver(this); 169 m_assetServer.SetReceiver(this);
170 170
171 m_assetCacheThread = new Thread(new ThreadStart(RunAssetManager)); 171 m_assetCacheThread = new Thread(new ThreadStart(RunAssetManager));
172 m_assetCacheThread.Name = "AssetCacheThread"; 172 m_assetCacheThread.Name = "AssetCacheThread";
173 m_assetCacheThread.IsBackground = true; 173 m_assetCacheThread.IsBackground = true;
174 m_assetCacheThread.Start(); 174 m_assetCacheThread.Start();
175 OpenSim.Framework.ThreadTracker.Add(m_assetCacheThread); 175 OpenSim.Framework.ThreadTracker.Add(m_assetCacheThread);
176 } 176 }
177 177
178 /// <summary> 178 /// <summary>
179 /// Process the asset queue which holds data which is packeted up and sent 179 /// Process the asset queue which holds data which is packeted up and sent
180 /// directly back to the client. 180 /// directly back to the client.
181 /// </summary> 181 /// </summary>
182 public void RunAssetManager() 182 public void RunAssetManager()
183 {
184 while (true)
185 { 183 {
186 try 184 while (true)
187 {
188 ProcessAssetQueue();
189 Thread.Sleep(500);
190 }
191 catch (Exception e)
192 { 185 {
193 m_log.Error("[ASSET CACHE]: " + e.ToString()); 186 try
187 {
188 ProcessAssetQueue();
189 Thread.Sleep(500);
190 }
191 catch (Exception e)
192 {
193 m_log.Error("[ASSET CACHE]: " + e.ToString());
194 }
194 } 195 }
195 } 196 }
196 }
197 197
198 /// <summary> 198 /// <summary>
199 /// Only get an asset if we already have it in the cache. 199 /// Only get an asset if we already have it in the cache.
@@ -265,6 +265,7 @@ namespace OpenSim.Framework.Communications.Cache
265 AssetRequestsList requestList; 265 AssetRequestsList requestList;
266 lock (RequestLists) 266 lock (RequestLists)
267 { 267 {
268 // m_log.Info("AssetCache: Lock taken on requestLists (GetAsset)");
268 if (RequestLists.TryGetValue(assetId, out requestList)) 269 if (RequestLists.TryGetValue(assetId, out requestList))
269 { 270 {
270 } 271 }
@@ -274,6 +275,7 @@ namespace OpenSim.Framework.Communications.Cache
274 RequestLists.Add(assetId, requestList); 275 RequestLists.Add(assetId, requestList);
275 } 276 }
276 } 277 }
278 // m_log.Info("AssetCache: Lock released on requestLists (GetAsset)");
277 279
278 requestList.Requests.Add(req); 280 requestList.Requests.Add(req);
279 281
@@ -447,19 +449,19 @@ namespace OpenSim.Framework.Communications.Cache
447 StatsManager.SimExtraStats.AddAsset(assetInf); 449 StatsManager.SimExtraStats.AddAsset(assetInf);
448 } 450 }
449 451
450 if (RequestedAssets.ContainsKey(assetInf.FullID)) 452 if (RequestedAssets.ContainsKey(assetInf.FullID))
451 { 453 {
452#if DEBUG 454 #if DEBUG
453 //m_log.DebugFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID); 455 //m_log.DebugFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID);
454#endif 456 #endif
455 457
456 AssetRequest req = RequestedAssets[assetInf.FullID]; 458 AssetRequest req = RequestedAssets[assetInf.FullID];
457 req.AssetInf = assetInf; 459 req.AssetInf = assetInf;
458 req.NumPackets = CalculateNumPackets(assetInf.Data); 460 req.NumPackets = CalculateNumPackets(assetInf.Data);
459 461
460 RequestedAssets.Remove(assetInf.FullID); 462 RequestedAssets.Remove(assetInf.FullID);
461 AssetRequests.Add(req); 463 AssetRequests.Add(req);
462 } 464 }
463 } 465 }
464 } 466 }
465 467
@@ -469,9 +471,11 @@ namespace OpenSim.Framework.Communications.Cache
469 AssetRequestsList reqList = null; 471 AssetRequestsList reqList = null;
470 lock (RequestLists) 472 lock (RequestLists)
471 { 473 {
474 //m_log.Info("AssetCache: Lock taken on requestLists (AssetReceived #1)");
472 reqList = RequestLists[asset.FullID]; 475 reqList = RequestLists[asset.FullID];
473 476
474 } 477 }
478 //m_log.Info("AssetCache: Lock released on requestLists (AssetReceived #1)");
475 if (reqList != null) 479 if (reqList != null)
476 { 480 {
477 //making a copy of the list is not ideal 481 //making a copy of the list is not ideal
@@ -486,8 +490,10 @@ namespace OpenSim.Framework.Communications.Cache
486 490
487 lock (RequestLists) 491 lock (RequestLists)
488 { 492 {
493 // m_log.Info("AssetCache: Lock taken on requestLists (AssetReceived #2)");
489 RequestLists.Remove(asset.FullID); 494 RequestLists.Remove(asset.FullID);
490 } 495 }
496 //m_log.Info("AssetCache: Lock released on requestLists (AssetReceived #2)");
491 497
492 foreach (NewAssetRequest req in theseRequests) 498 foreach (NewAssetRequest req in theseRequests)
493 { 499 {
@@ -501,217 +507,234 @@ namespace OpenSim.Framework.Communications.Cache
501 // See IAssetReceiver 507 // See IAssetReceiver
502 public void AssetNotFound(LLUUID assetID) 508 public void AssetNotFound(LLUUID assetID)
503 { 509 {
504 m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID); 510 // m_log.WarnFormat("[ASSET CACHE]: AssetNotFound for {0}", assetID);
505 511
506 // Notify requesters for this asset 512 // Notify requesters for this asset
513 AssetRequestsList reqList = null;
507 lock (RequestLists) 514 lock (RequestLists)
508 { 515 {
516 // m_log.Info("AssetCache: Lock taken on requestLists (AssetNotFound #1)");
509 if (RequestLists.ContainsKey(assetID)) 517 if (RequestLists.ContainsKey(assetID))
510 { 518 {
511 AssetRequestsList reqList = RequestLists[assetID]; 519 reqList = RequestLists[assetID];
512 foreach (NewAssetRequest req in reqList.Requests)
513 {
514 req.Callback(assetID, null);
515 }
516
517 RequestLists.Remove(assetID);
518 } 520 }
519 } 521 }
520 } 522 // m_log.Info("AssetCache: Lock released on requestLists (AssetNotFound #1)");
521
522 /// <summary>
523 /// Calculate the number of packets required to send the asset to the client.
524 /// </summary>
525 /// <param name="data"></param>
526 /// <returns></returns>
527 private int CalculateNumPackets(byte[] data)
528 {
529 const uint m_maxPacketSize = 600;
530 int numPackets = 1;
531 523
532 if (data.LongLength > m_maxPacketSize) 524 if (reqList != null)
533 { 525 {
534 // over max number of bytes so split up file 526 List<NewAssetRequest> theseRequests = new List<NewAssetRequest>(reqList.Requests);
535 long restData = data.LongLength - m_maxPacketSize; 527 reqList.Requests.Clear();
536 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
537 numPackets += restPackets;
538 }
539 528
540 return numPackets; 529 lock (RequestLists)
541 }
542
543 /// <summary>
544 /// Make an asset request the result of which will be packeted up and sent directly back to the client.
545 /// </summary>
546 /// <param name="userInfo"></param>
547 /// <param name="transferRequest"></param>
548 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
549 {
550 LLUUID requestID = null;
551 byte source = 2;
552 if (transferRequest.TransferInfo.SourceType == 2)
553 {
554 //direct asset request
555 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
556 }
557 else if (transferRequest.TransferInfo.SourceType == 3)
558 {
559 //inventory asset request
560 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
561 source = 3;
562 //Console.WriteLine("asset request " + requestID);
563 }
564 //check to see if asset is in local cache, if not we need to request it from asset server.
565 //Console.WriteLine("asset request " + requestID);
566 if (!Assets.ContainsKey(requestID))
567 {
568 //not found asset
569 // so request from asset server
570 if (!RequestedAssets.ContainsKey(requestID))
571 {
572 AssetRequest request = new AssetRequest();
573 request.RequestUser = userInfo;
574 request.RequestAssetID = requestID;
575 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
576 request.AssetRequestSource = source;
577 request.Params = transferRequest.TransferInfo.Params;
578 RequestedAssets.Add(requestID, request);
579 m_assetServer.RequestAsset(requestID, false);
580 }
581 return;
582 }
583 //it is in our cache
584 AssetInfo asset = Assets[requestID];
585
586 // add to the AssetRequests list
587 AssetRequest req = new AssetRequest();
588 req.RequestUser = userInfo;
589 req.RequestAssetID = requestID;
590 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
591 req.AssetRequestSource = source;
592 req.Params = transferRequest.TransferInfo.Params;
593 req.AssetInf = asset;
594 req.NumPackets = CalculateNumPackets(asset.Data);
595 AssetRequests.Add(req);
596 }
597
598 /// <summary>
599 /// Process the asset queue which sends packets directly back to the client.
600 /// </summary>
601 private void ProcessAssetQueue()
602 {
603 //should move the asset downloading to a module, like has been done with texture downloading
604 if (AssetRequests.Count == 0)
605 {
606 //no requests waiting
607 return;
608 }
609 // if less than 5, do all of them
610 int num = Math.Min(5, AssetRequests.Count);
611
612 AssetRequest req;
613 for (int i = 0; i < num; i++)
614 {
615 req = (AssetRequest)AssetRequests[i];
616 //Console.WriteLine("sending asset " + req.RequestAssetID);
617 TransferInfoPacket Transfer = new TransferInfoPacket();
618 Transfer.TransferInfo.ChannelType = 2;
619 Transfer.TransferInfo.Status = 0;
620 Transfer.TransferInfo.TargetType = 0;
621 if (req.AssetRequestSource == 2)
622 {
623 Transfer.TransferInfo.Params = new byte[20];
624 Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
625 int assType = (int)req.AssetInf.Type;
626 Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
627 }
628 else if (req.AssetRequestSource == 3)
629 { 530 {
630 Transfer.TransferInfo.Params = req.Params; 531 // m_log.Info("AssetCache: Lock taken on requestLists (AssetNotFound #2)");
631 // Transfer.TransferInfo.Params = new byte[100]; 532 RequestLists.Remove(assetID);
632 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
633 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
634 } 533 }
635 Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; 534 // m_log.Info("AssetCache: Lock released on requestLists (AssetNotFound #2)");
636 Transfer.TransferInfo.TransferID = req.TransferRequestID;
637 req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
638 535
639 if (req.NumPackets == 1) 536 foreach (NewAssetRequest req in theseRequests)
640 { 537 {
641 TransferPacketPacket TransferPacket = new TransferPacketPacket(); 538 req.Callback(assetID, null);
642 TransferPacket.TransferData.Packet = 0;
643 TransferPacket.TransferData.ChannelType = 2;
644 TransferPacket.TransferData.TransferID = req.TransferRequestID;
645 TransferPacket.TransferData.Data = req.AssetInf.Data;
646 TransferPacket.TransferData.Status = 1;
647 req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
648 }
649 else
650 {
651 int processedLength = 0;
652 // libsecondlife hardcodes 1500 as the maximum data chunk size
653 int maxChunkSize = 1250;
654 int packetNumber = 0;
655
656 while (processedLength < req.AssetInf.Data.Length)
657 {
658 TransferPacketPacket TransferPacket = new TransferPacketPacket();
659 TransferPacket.TransferData.Packet = packetNumber;
660 TransferPacket.TransferData.ChannelType = 2;
661 TransferPacket.TransferData.TransferID = req.TransferRequestID;
662
663 int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
664 byte[] chunk = new byte[chunkSize];
665 Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
666
667 TransferPacket.TransferData.Data = chunk;
668
669 // 0 indicates more packets to come, 1 indicates last packet
670 if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
671 {
672 TransferPacket.TransferData.Status = 0;
673 }
674 else
675 {
676 TransferPacket.TransferData.Status = 1;
677 }
678
679 req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
680
681 processedLength += chunkSize;
682 packetNumber++;
683 }
684 } 539 }
685 } 540 }
686 541
687 //remove requests that have been completed
688 for (int i = 0; i < num; i++)
689 {
690 AssetRequests.RemoveAt(0);
691 }
692 } 542 }
693 543
694 public class AssetRequest 544 /// <summary>
695 { 545 /// Calculate the number of packets required to send the asset to the client.
696 public IClientAPI RequestUser; 546 /// </summary>
697 public LLUUID RequestAssetID; 547 /// <param name="data"></param>
698 public AssetInfo AssetInf; 548 /// <returns></returns>
699 public TextureImage ImageInfo; 549 private int CalculateNumPackets(byte[] data)
700 public LLUUID TransferRequestID; 550 {
701 public long DataPointer = 0; 551 const uint m_maxPacketSize = 600;
702 public int NumPackets = 0; 552 int numPackets = 1;
703 public int PacketCounter = 0; 553
704 public bool IsTextureRequest; 554 if (data.LongLength > m_maxPacketSize)
705 public byte AssetRequestSource = 2; 555 {
706 public byte[] Params = null; 556 // over max number of bytes so split up file
707 //public bool AssetInCache; 557 long restData = data.LongLength - m_maxPacketSize;
708 //public int TimeRequested; 558 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
709 public int DiscardLevel = -1; 559 numPackets += restPackets;
710 560 }
711 public AssetRequest() 561
712 { 562 return numPackets;
713 } 563 }
714 } 564
565 /// <summary>
566 /// Make an asset request the result of which will be packeted up and sent directly back to the client.
567 /// </summary>
568 /// <param name="userInfo"></param>
569 /// <param name="transferRequest"></param>
570 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
571 {
572 LLUUID requestID = null;
573 byte source = 2;
574 if (transferRequest.TransferInfo.SourceType == 2)
575 {
576 //direct asset request
577 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
578 }
579 else if (transferRequest.TransferInfo.SourceType == 3)
580 {
581 //inventory asset request
582 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
583 source = 3;
584 //Console.WriteLine("asset request " + requestID);
585 }
586 //check to see if asset is in local cache, if not we need to request it from asset server.
587 //Console.WriteLine("asset request " + requestID);
588 if (!Assets.ContainsKey(requestID))
589 {
590 //not found asset
591 // so request from asset server
592 if (!RequestedAssets.ContainsKey(requestID))
593 {
594 AssetRequest request = new AssetRequest();
595 request.RequestUser = userInfo;
596 request.RequestAssetID = requestID;
597 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
598 request.AssetRequestSource = source;
599 request.Params = transferRequest.TransferInfo.Params;
600 RequestedAssets.Add(requestID, request);
601 m_assetServer.RequestAsset(requestID, false);
602 }
603 return;
604 }
605 //it is in our cache
606 AssetInfo asset = Assets[requestID];
607
608 // add to the AssetRequests list
609 AssetRequest req = new AssetRequest();
610 req.RequestUser = userInfo;
611 req.RequestAssetID = requestID;
612 req.TransferRequestID = transferRequest.TransferInfo.TransferID;
613 req.AssetRequestSource = source;
614 req.Params = transferRequest.TransferInfo.Params;
615 req.AssetInf = asset;
616 req.NumPackets = CalculateNumPackets(asset.Data);
617 AssetRequests.Add(req);
618 }
619
620 /// <summary>
621 /// Process the asset queue which sends packets directly back to the client.
622 /// </summary>
623 private void ProcessAssetQueue()
624 {
625 //should move the asset downloading to a module, like has been done with texture downloading
626 if (AssetRequests.Count == 0)
627 {
628 //no requests waiting
629 return;
630 }
631 // if less than 5, do all of them
632 int num = Math.Min(5, AssetRequests.Count);
633
634 AssetRequest req;
635 for (int i = 0; i < num; i++)
636 {
637 req = (AssetRequest)AssetRequests[i];
638 //Console.WriteLine("sending asset " + req.RequestAssetID);
639 TransferInfoPacket Transfer = new TransferInfoPacket();
640 Transfer.TransferInfo.ChannelType = 2;
641 Transfer.TransferInfo.Status = 0;
642 Transfer.TransferInfo.TargetType = 0;
643 if (req.AssetRequestSource == 2)
644 {
645 Transfer.TransferInfo.Params = new byte[20];
646 Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
647 int assType = (int)req.AssetInf.Type;
648 Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
649 }
650 else if (req.AssetRequestSource == 3)
651 {
652 Transfer.TransferInfo.Params = req.Params;
653 // Transfer.TransferInfo.Params = new byte[100];
654 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
655 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
656 }
657 Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
658 Transfer.TransferInfo.TransferID = req.TransferRequestID;
659 req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
660
661 if (req.NumPackets == 1)
662 {
663 TransferPacketPacket TransferPacket = new TransferPacketPacket();
664 TransferPacket.TransferData.Packet = 0;
665 TransferPacket.TransferData.ChannelType = 2;
666 TransferPacket.TransferData.TransferID = req.TransferRequestID;
667 TransferPacket.TransferData.Data = req.AssetInf.Data;
668 TransferPacket.TransferData.Status = 1;
669 req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
670 }
671 else
672 {
673 int processedLength = 0;
674 // libsecondlife hardcodes 1500 as the maximum data chunk size
675 int maxChunkSize = 1250;
676 int packetNumber = 0;
677
678 while (processedLength < req.AssetInf.Data.Length)
679 {
680 TransferPacketPacket TransferPacket = new TransferPacketPacket();
681 TransferPacket.TransferData.Packet = packetNumber;
682 TransferPacket.TransferData.ChannelType = 2;
683 TransferPacket.TransferData.TransferID = req.TransferRequestID;
684
685 int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
686 byte[] chunk = new byte[chunkSize];
687 Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
688
689 TransferPacket.TransferData.Data = chunk;
690
691 // 0 indicates more packets to come, 1 indicates last packet
692 if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
693 {
694 TransferPacket.TransferData.Status = 0;
695 }
696 else
697 {
698 TransferPacket.TransferData.Status = 1;
699 }
700
701 req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
702
703 processedLength += chunkSize;
704 packetNumber++;
705 }
706 }
707 }
708
709 //remove requests that have been completed
710 for (int i = 0; i < num; i++)
711 {
712 AssetRequests.RemoveAt(0);
713 }
714 }
715
716 public class AssetRequest
717 {
718 public IClientAPI RequestUser;
719 public LLUUID RequestAssetID;
720 public AssetInfo AssetInf;
721 public TextureImage ImageInfo;
722 public LLUUID TransferRequestID;
723 public long DataPointer = 0;
724 public int NumPackets = 0;
725 public int PacketCounter = 0;
726 public bool IsTextureRequest;
727 public byte AssetRequestSource = 2;
728 public byte[] Params = null;
729 //public bool AssetInCache;
730 //public int TimeRequested;
731 public int DiscardLevel = -1;
732
733 public AssetRequest()
734 {
735 }
736 }
737
715 738
716 public class AssetInfo : AssetBase 739 public class AssetInfo : AssetBase
717 { 740 {