aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/Cache/AssetCache.cs
diff options
context:
space:
mode:
authorMW2007-12-10 13:27:23 +0000
committerMW2007-12-10 13:27:23 +0000
commit611327e1040fa706665c543f67f9331a7e0136c5 (patch)
tree4426a50291dbc1c7c4ec065fd5c48921a767b658 /OpenSim/Framework/Communications/Cache/AssetCache.cs
parentadded musings on llInstantMessage (diff)
downloadopensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.zip
opensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.tar.gz
opensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.tar.bz2
opensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.tar.xz
more work on texture downloading.
Refractored the TextureDownloadModule (but currently to make debugging easier, it is running as a non shared module, so this results in a instance of this module being created for each region (and a extra thread per region), this will be changed back soon. Removed the old texture handling/sending code from AssetCache. A few other small changes/fixes.
Diffstat (limited to 'OpenSim/Framework/Communications/Cache/AssetCache.cs')
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs303
1 files changed, 38 insertions, 265 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index d5ac67b..c164f0c 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -36,8 +36,7 @@ using OpenSim.Framework.Console;
36 36
37namespace OpenSim.Framework.Communications.Cache 37namespace OpenSim.Framework.Communications.Cache
38{ 38{
39 public delegate void DownloadComplete(AssetCache.TextureSender sender); 39
40
41 public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset); 40 public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset);
42 41
43 /// <summary> 42 /// <summary>
@@ -57,21 +56,11 @@ namespace OpenSim.Framework.Communications.Cache
57 public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); 56 public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>();
58 //Textures requested from the asset server 57 //Textures requested from the asset server
59 58
60 public Dictionary<LLUUID, TextureSender> SendingTextures = new Dictionary<LLUUID, TextureSender>();
61
62 public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); 59 public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>();
63 60
64 private BlockingQueue<TextureSender> m_queueTextures = new BlockingQueue<TextureSender>();
65 private Dictionary<LLUUID, List<LLUUID>> m_avatarReceivedTextures = new Dictionary<LLUUID, List<LLUUID>>();
66
67 private Dictionary<LLUUID, Dictionary<LLUUID, int>> m_timesTextureSent =
68 new Dictionary<LLUUID, Dictionary<LLUUID, int>>();
69
70
71 private IAssetServer m_assetServer; 61 private IAssetServer m_assetServer;
72 62
73 private Thread m_assetCacheThread; 63 private Thread m_assetCacheThread;
74 private Thread m_textureSenderThread;
75 private LogBase m_log; 64 private LogBase m_log;
76 65
77 /// <summary> 66 /// <summary>
@@ -88,9 +77,7 @@ namespace OpenSim.Framework.Communications.Cache
88 m_assetCacheThread.IsBackground = true; 77 m_assetCacheThread.IsBackground = true;
89 m_assetCacheThread.Start(); 78 m_assetCacheThread.Start();
90 79
91 m_textureSenderThread = new Thread(new ThreadStart(ProcessTextureSenders)); 80
92 m_textureSenderThread.IsBackground = true;
93 m_textureSenderThread.Start();
94 m_log = log; 81 m_log = log;
95 } 82 }
96 83
@@ -104,7 +91,6 @@ namespace OpenSim.Framework.Communications.Cache
104 try 91 try
105 { 92 {
106 ProcessAssetQueue(); 93 ProcessAssetQueue();
107 ProcessTextureQueue();
108 Thread.Sleep(500); 94 Thread.Sleep(500);
109 } 95 }
110 catch (Exception e) 96 catch (Exception e)
@@ -188,7 +174,7 @@ namespace OpenSim.Framework.Communications.Cache
188 174
189 if (asset.Type == 0) 175 if (asset.Type == 0)
190 { 176 {
191 if(Textures.ContainsKey(asset.FullID)) 177 if (Textures.ContainsKey(asset.FullID))
192 { 178 {
193 result = "Duplicate ignored."; 179 result = "Duplicate ignored.";
194 } 180 }
@@ -250,67 +236,7 @@ namespace OpenSim.Framework.Communications.Cache
250 return asset; 236 return asset;
251 } 237 }
252 238
253 /// <summary>
254 ///
255 /// </summary>
256 private void ProcessTextureQueue()
257 {
258 if (TextureRequests.Count == 0)
259 {
260 //no requests waiting
261 return;
262 }
263 int num;
264 num = TextureRequests.Count;
265 239
266 AssetRequest req;
267 for (int i = 0; i < num; i++)
268 {
269 req = (AssetRequest) TextureRequests[i];
270 if (!SendingTextures.ContainsKey(req.ImageInfo.FullID))
271 {
272 //Console.WriteLine("new texture to send");
273 TextureSender sender = new TextureSender(req);
274 //sender.OnComplete += this.TextureSent;
275 SendingTextures.Add(req.ImageInfo.FullID, sender);
276 m_queueTextures.Enqueue(sender);
277 }
278 }
279
280 TextureRequests.Clear();
281 }
282
283 public void ProcessTextureSenders()
284 {
285 while (true)
286 {
287 TextureSender sender = m_queueTextures.Dequeue();
288
289 bool finished = sender.SendTexture();
290 if (finished)
291 {
292 TextureSent(sender);
293 }
294 else
295 {
296 // Console.WriteLine("readding texture");
297 m_queueTextures.Enqueue(sender);
298 }
299 }
300 }
301
302 /// <summary>
303 /// Event handler, called by a TextureSender object to say that texture has been sent
304 /// </summary>
305 /// <param name="sender"></param>
306 public void TextureSent(TextureSender sender)
307 {
308 if (SendingTextures.ContainsKey(sender.request.ImageInfo.FullID))
309 {
310 SendingTextures.Remove(sender.request.ImageInfo.FullID);
311 // this.m_avatarReceivedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID);
312 }
313 }
314 240
315 public void AssetReceived(AssetBase asset, bool IsTexture) 241 public void AssetReceived(AssetBase asset, bool IsTexture)
316 { 242 {
@@ -354,7 +280,7 @@ namespace OpenSim.Framework.Communications.Cache
354 if (assetInf.Data.LongLength > 600) 280 if (assetInf.Data.LongLength > 600)
355 { 281 {
356 //over 600 bytes so split up file 282 //over 600 bytes so split up file
357 req.NumPackets = 1 + (int) (assetInf.Data.Length - 600 + 999)/1000; 283 req.NumPackets = 1 + (int)(assetInf.Data.Length - 600 + 999) / 1000;
358 } 284 }
359 else 285 else
360 { 286 {
@@ -400,6 +326,20 @@ namespace OpenSim.Framework.Communications.Cache
400 //} 326 //}
401 } 327 }
402 328
329 private int CalculateNumPackets(int length)
330 {
331 int numPackets = 1;
332
333 if (length > 600)
334 {
335 //over 600 bytes so split up file
336 int restData = (length - 600);
337 int restPackets = ((restData + 999) / 1000);
338 numPackets = 1 + restPackets;
339 }
340
341 return numPackets;
342 }
403 #region Assets 343 #region Assets
404 344
405 /// <summary> 345 /// <summary>
@@ -458,7 +398,7 @@ namespace OpenSim.Framework.Communications.Cache
458 if (asset.Data.LongLength > 600) 398 if (asset.Data.LongLength > 600)
459 { 399 {
460 //over 600 bytes so split up file 400 //over 600 bytes so split up file
461 req.NumPackets = 1 + (int) (asset.Data.Length - 600 + 999)/1000; 401 req.NumPackets = 1 + (int)(asset.Data.Length - 600 + 999) / 1000;
462 } 402 }
463 else 403 else
464 { 404 {
@@ -473,6 +413,7 @@ namespace OpenSim.Framework.Communications.Cache
473 /// </summary> 413 /// </summary>
474 private void ProcessAssetQueue() 414 private void ProcessAssetQueue()
475 { 415 {
416 //should move the asset downloading to a module, like has been done with texture downloading
476 if (AssetRequests.Count == 0) 417 if (AssetRequests.Count == 0)
477 { 418 {
478 //no requests waiting 419 //no requests waiting
@@ -492,7 +433,7 @@ namespace OpenSim.Framework.Communications.Cache
492 AssetRequest req; 433 AssetRequest req;
493 for (int i = 0; i < num; i++) 434 for (int i = 0; i < num; i++)
494 { 435 {
495 req = (AssetRequest) AssetRequests[i]; 436 req = (AssetRequest)AssetRequests[i];
496 //Console.WriteLine("sending asset " + req.RequestAssetID); 437 //Console.WriteLine("sending asset " + req.RequestAssetID);
497 TransferInfoPacket Transfer = new TransferInfoPacket(); 438 TransferInfoPacket Transfer = new TransferInfoPacket();
498 Transfer.TransferInfo.ChannelType = 2; 439 Transfer.TransferInfo.ChannelType = 2;
@@ -502,7 +443,7 @@ namespace OpenSim.Framework.Communications.Cache
502 { 443 {
503 Transfer.TransferInfo.Params = new byte[20]; 444 Transfer.TransferInfo.Params = new byte[20];
504 Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 445 Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
505 int assType = (int) req.AssetInf.Type; 446 int assType = (int)req.AssetInf.Type;
506 Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); 447 Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
507 } 448 }
508 else if (req.AssetRequestSource == 3) 449 else if (req.AssetRequestSource == 3)
@@ -512,9 +453,9 @@ namespace OpenSim.Framework.Communications.Cache
512 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 453 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
513 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); 454 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
514 } 455 }
515 Transfer.TransferInfo.Size = (int) req.AssetInf.Data.Length; 456 Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
516 Transfer.TransferInfo.TransferID = req.TransferRequestID; 457 Transfer.TransferInfo.TransferID = req.TransferRequestID;
517 req.RequestUser.OutPacket(Transfer,ThrottleOutPacketType.Asset); 458 req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
518 459
519 if (req.NumPackets == 1) 460 if (req.NumPackets == 1)
520 { 461 {
@@ -573,79 +514,6 @@ namespace OpenSim.Framework.Communications.Cache
573 514
574 #endregion 515 #endregion
575 516
576 #region Textures
577
578 /// <summary>
579 ///
580 /// </summary>
581 /// <param name="userInfo"></param>
582 /// <param name="imageID"></param>
583 public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID, uint packetNumber, int discard)
584 {
585 // System.Console.WriteLine("texture request for " + imageID.ToStringHyphenated() + " packetnumber= " + packetNumber);
586 //check to see if texture is in local cache, if not request from asset server
587 if (!m_avatarReceivedTextures.ContainsKey(userInfo.AgentId))
588 {
589 m_avatarReceivedTextures.Add(userInfo.AgentId, new List<LLUUID>());
590 }
591 /* if(this.m_avatarReceivedTextures[userInfo.AgentId].Contains(imageID))
592 {
593 //Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them");
594 return;
595 }*/
596
597 if (!Textures.ContainsKey(imageID))
598 {
599 if (!RequestedTextures.ContainsKey(imageID))
600 {
601 //not is cache so request from asset server
602 AssetRequest request = new AssetRequest();
603 request.RequestUser = userInfo;
604 request.RequestAssetID = imageID;
605 request.IsTextureRequest = true;
606 request.DiscardLevel = discard;
607 RequestedTextures.Add(imageID, request);
608 m_assetServer.RequestAsset(imageID, true);
609 }
610 return;
611 }
612
613 // System.Console.WriteLine("texture already in cache");
614 TextureImage imag = Textures[imageID];
615 AssetRequest req = new AssetRequest();
616 req.RequestUser = userInfo;
617 req.RequestAssetID = imageID;
618 req.IsTextureRequest = true;
619 req.ImageInfo = imag;
620 req.DiscardLevel = discard;
621
622 req.NumPackets = CalculateNumPackets(imag.Data.Length);
623
624 if (packetNumber != 0)
625 {
626 req.PacketCounter = (int) packetNumber;
627 }
628
629 TextureRequests.Add(req);
630 }
631
632 private int CalculateNumPackets(int length)
633 {
634 int numPackets = 1;
635
636 if (length > 600)
637 {
638 //over 600 bytes so split up file
639 int restData = (length - 600);
640 int restPackets = ((restData+999)/1000);
641 numPackets = 1 + restPackets;
642 }
643
644 return numPackets;
645 }
646
647 #endregion
648
649 public class AssetRequest 517 public class AssetRequest
650 { 518 {
651 public IClientAPI RequestUser; 519 public IClientAPI RequestUser;
@@ -702,123 +570,28 @@ namespace OpenSim.Framework.Communications.Cache
702 } 570 }
703 } 571 }
704 572
705 public class TextureSender
706 {
707 public AssetRequest request;
708 private int counter = 0;
709
710 public TextureSender(AssetRequest req)
711 {
712 request = req;
713 }
714
715 public bool SendTexture()
716 {
717 SendPacket();
718 counter++;
719
720 if ((request.PacketCounter >= request.NumPackets) || counter > 100 || (request.NumPackets == 1) ||
721 (request.DiscardLevel == -1))
722 {
723 return true;
724 }
725 return false;
726 }
727 573
728 public void SendPacket() 574 public class AssetRequestsList
729 { 575 {
730 AssetRequest req = request; 576 public LLUUID AssetID;
731 //Console.WriteLine("sending " + req.ImageInfo.FullID); 577 public List<NewAssetRequest> Requests = new List<NewAssetRequest>();
732 if (req.PacketCounter == 0)
733 {
734 //first time for this request so send imagedata packet
735 if (req.NumPackets == 1)
736 {
737 //Console.WriteLine("only one packet so send whole file");
738 ImageDataPacket im = new ImageDataPacket();
739 im.Header.Reliable = false;
740 im.ImageID.Packets = 1;
741 im.ImageID.ID = req.ImageInfo.FullID;
742 im.ImageID.Size = (uint) req.ImageInfo.Data.Length;
743 im.ImageData.Data = req.ImageInfo.Data;
744 im.ImageID.Codec = 2;
745 req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
746 req.PacketCounter++;
747 //req.ImageInfo.l= time;
748 //System.Console.WriteLine("sent texture: " + req.ImageInfo.FullID);
749 //Console.WriteLine("sending single packet for " + req.ImageInfo.FullID.ToStringHyphenated());
750 }
751 else
752 {
753 //more than one packet so split file up
754 ImageDataPacket im = new ImageDataPacket();
755 im.Header.Reliable = false;
756 im.ImageID.Packets = (ushort) (req.NumPackets);
757 im.ImageID.ID = req.ImageInfo.FullID;
758 im.ImageID.Size = (uint) req.ImageInfo.Data.Length;
759 im.ImageData.Data = new byte[600];
760 Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600);
761 im.ImageID.Codec = 2;
762 req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
763
764 req.PacketCounter++;
765 //req.ImageInfo.last_used = time;
766 //System.Console.WriteLine("sent first packet of texture: " + req.ImageInfo.FullID);
767 //Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated());
768 }
769 }
770 else
771 {
772 //Console.WriteLine("sending packet " + req.PacketCounter + " for " + req.ImageInfo.FullID.ToStringHyphenated());
773 //send imagepacket
774 //more than one packet so split file up
775 ImagePacketPacket im = new ImagePacketPacket();
776 im.Header.Reliable = false;
777 im.ImageID.Packet = (ushort) (req.PacketCounter);
778 im.ImageID.ID = req.ImageInfo.FullID;
779 int size = req.ImageInfo.Data.Length - 600 - (1000*(req.PacketCounter - 1));
780 if (size > 1000) size = 1000;
781 //Console.WriteLine("length= {0} counter= {1} size= {2}",req.ImageInfo.Data.Length, req.PacketCounter, size);
782 im.ImageData.Data = new byte[size];
783 Array.Copy(req.ImageInfo.Data, 600 + (1000*(req.PacketCounter - 1)), im.ImageData.Data, 0, size);
784 req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
785 req.PacketCounter++;
786 //req.ImageInfo.last_used = time;
787 //System.Console.WriteLine("sent a packet of texture: "+req.ImageInfo.FullID);
788 }
789 }
790 578
791 private void SaveAssetToFile(string filename, byte[] data) 579 public AssetRequestsList(LLUUID assetID)
792 { 580 {
793 FileStream fs = File.Create(filename); 581 AssetID = assetID;
794 BinaryWriter bw = new BinaryWriter(fs);
795 bw.Write(data);
796 bw.Close();
797 fs.Close();
798 } 582 }
799 } 583 }
800 }
801
802 public class AssetRequestsList
803 {
804 public LLUUID AssetID;
805 public List<NewAssetRequest> Requests = new List<NewAssetRequest>();
806 584
807 public AssetRequestsList(LLUUID assetID) 585 public class NewAssetRequest
808 { 586 {
809 AssetID = assetID; 587 public LLUUID AssetID;
810 } 588 public AssetRequestCallback Callback;
811 }
812
813 public class NewAssetRequest
814 {
815 public LLUUID AssetID;
816 public AssetRequestCallback Callback;
817 589
818 public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) 590 public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback)
819 { 591 {
820 AssetID = assetID; 592 AssetID = assetID;
821 Callback = callback; 593 Callback = callback;
594 }
822 } 595 }
823 } 596 }
824} 597}