aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs118
1 files changed, 83 insertions, 35 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index e4c01b3..ca74724 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -28,12 +28,14 @@
28 28
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33using libsecondlife; 34using libsecondlife;
34using libsecondlife.Packets; 35using libsecondlife.Packets;
35using OpenSim.Framework.Interfaces; 36using OpenSim.Framework.Interfaces;
36using OpenSim.Framework.Types; 37using OpenSim.Framework.Types;
38using OpenSim.Framework.Utilities;
37 39
38namespace OpenSim.Framework.Communications.Caches 40namespace OpenSim.Framework.Communications.Caches
39{ 41{
@@ -54,9 +56,15 @@ namespace OpenSim.Framework.Communications.Caches
54 public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); //Textures requested from the asset server 56 public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); //Textures requested from the asset server
55 57
56 public Dictionary<LLUUID, TextureSender> SendingTextures = new Dictionary<LLUUID, TextureSender>(); 58 public Dictionary<LLUUID, TextureSender> SendingTextures = new Dictionary<LLUUID, TextureSender>();
59 private BlockingQueue<TextureSender> QueueTextures = new BlockingQueue<TextureSender>();
60
61 private Dictionary<LLUUID, List<LLUUID>> AvatarRecievedTextures = new Dictionary<LLUUID,List<LLUUID>>();
62
57 private IAssetServer _assetServer; 63 private IAssetServer _assetServer;
58 private Thread _assetCacheThread; 64 private Thread _assetCacheThread;
59 65
66 private Thread TextureSenderThread;
67
60 /// <summary> 68 /// <summary>
61 /// 69 ///
62 /// </summary> 70 /// </summary>
@@ -71,6 +79,10 @@ namespace OpenSim.Framework.Communications.Caches
71 this._assetCacheThread.IsBackground = true; 79 this._assetCacheThread.IsBackground = true;
72 this._assetCacheThread.Start(); 80 this._assetCacheThread.Start();
73 81
82 this.TextureSenderThread = new Thread(new ThreadStart(this.ProcessTextureSenders));
83 this.TextureSenderThread.IsBackground = true;
84 this.TextureSenderThread.Start();
85
74 } 86 }
75 87
76 public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey) 88 public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey)
@@ -85,6 +97,9 @@ namespace OpenSim.Framework.Communications.Caches
85 this._assetCacheThread.IsBackground = true; 97 this._assetCacheThread.IsBackground = true;
86 this._assetCacheThread.Start(); 98 this._assetCacheThread.Start();
87 99
100 this.TextureSenderThread = new Thread(new ThreadStart(this.ProcessTextureSenders));
101 this.TextureSenderThread.IsBackground = true;
102 this.TextureSenderThread.Start();
88 } 103 }
89 104
90 /// <summary> 105 /// <summary>
@@ -165,12 +180,14 @@ namespace OpenSim.Framework.Communications.Caches
165 req = (AssetRequest)this.TextureRequests[i]; 180 req = (AssetRequest)this.TextureRequests[i];
166 if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID)) 181 if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID))
167 { 182 {
183 //Console.WriteLine("new texture to send");
168 TextureSender sender = new TextureSender(req); 184 TextureSender sender = new TextureSender(req);
169 sender.OnComplete += this.TextureSent; 185 //sender.OnComplete += this.TextureSent;
170 lock (this.SendingTextures) 186 lock (this.SendingTextures)
171 { 187 {
172 this.SendingTextures.Add(req.ImageInfo.FullID, sender); 188 this.SendingTextures.Add(req.ImageInfo.FullID, sender);
173 } 189 }
190 this.QueueTextures.Enqueue(sender);
174 } 191 }
175 192
176 } 193 }
@@ -178,6 +195,25 @@ namespace OpenSim.Framework.Communications.Caches
178 this.TextureRequests.Clear(); 195 this.TextureRequests.Clear();
179 } 196 }
180 197
198 public void ProcessTextureSenders()
199 {
200 while (true)
201 {
202 TextureSender sender = this.QueueTextures.Dequeue();
203 bool finished = sender.SendTexture();
204 if (finished)
205 {
206 this.TextureSent(sender);
207 }
208 else
209 {
210 // Console.WriteLine("readding texture");
211 this.QueueTextures.Enqueue(sender);
212 }
213 }
214
215 }
216
181 /// <summary> 217 /// <summary>
182 /// Event handler, called by a TextureSender object to say that texture has been sent 218 /// Event handler, called by a TextureSender object to say that texture has been sent
183 /// </summary> 219 /// </summary>
@@ -189,6 +225,7 @@ namespace OpenSim.Framework.Communications.Caches
189 lock (this.SendingTextures) 225 lock (this.SendingTextures)
190 { 226 {
191 this.SendingTextures.Remove(sender.request.ImageInfo.FullID); 227 this.SendingTextures.Remove(sender.request.ImageInfo.FullID);
228 this.AvatarRecievedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID);
192 } 229 }
193 } 230 }
194 } 231 }
@@ -201,8 +238,10 @@ namespace OpenSim.Framework.Communications.Caches
201 //then add to the correct cache list 238 //then add to the correct cache list
202 //then check for waiting requests for this asset/texture (in the Requested lists) 239 //then check for waiting requests for this asset/texture (in the Requested lists)
203 //and move those requests into the Requests list. 240 //and move those requests into the Requests list.
241
204 if (IsTexture) 242 if (IsTexture)
205 { 243 {
244 // Console.WriteLine("asset recieved from asset server");
206 TextureImage image = new TextureImage(asset); 245 TextureImage image = new TextureImage(asset);
207 this.Textures.Add(image.FullID, image); 246 this.Textures.Add(image.FullID, image);
208 if (this.RequestedTextures.ContainsKey(image.FullID)) 247 if (this.RequestedTextures.ContainsKey(image.FullID))
@@ -212,7 +251,7 @@ namespace OpenSim.Framework.Communications.Caches
212 if (image.Data.LongLength > 600) 251 if (image.Data.LongLength > 600)
213 { 252 {
214 //over 600 bytes so split up file 253 //over 600 bytes so split up file
215 req.NumPackets = 1 + (int)(image.Data.Length - 600 + 999) / 1000; 254 req.NumPackets = 1 + (int)(image.Data.Length - 600 ) / 1000;
216 } 255 }
217 else 256 else
218 { 257 {
@@ -260,7 +299,7 @@ namespace OpenSim.Framework.Communications.Caches
260 /// <param name="transferRequest"></param> 299 /// <param name="transferRequest"></param>
261 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) 300 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
262 { 301 {
263 LLUUID requestID = null; 302 LLUUID requestID = null;
264 byte source = 2; 303 byte source = 2;
265 if (transferRequest.TransferInfo.SourceType == 2) 304 if (transferRequest.TransferInfo.SourceType == 2)
266 { 305 {
@@ -359,7 +398,7 @@ namespace OpenSim.Framework.Communications.Caches
359 else if (req.AssetRequestSource == 3) 398 else if (req.AssetRequestSource == 3)
360 { 399 {
361 Transfer.TransferInfo.Params = req.Params; 400 Transfer.TransferInfo.Params = req.Params;
362 // Transfer.TransferInfo.Params = new byte[100]; 401 // Transfer.TransferInfo.Params = new byte[100];
363 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 402 //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
364 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); 403 //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
365 } 404 }
@@ -411,7 +450,7 @@ namespace OpenSim.Framework.Communications.Caches
411 TransferPacket.TransferData.Data = chunk1; 450 TransferPacket.TransferData.Data = chunk1;
412 TransferPacket.TransferData.Status = 1; 451 TransferPacket.TransferData.Status = 1;
413 req.RequestUser.OutPacket(TransferPacket); 452 req.RequestUser.OutPacket(TransferPacket);
414 } 453 }
415 } 454 }
416 455
417 } 456 }
@@ -444,8 +483,17 @@ namespace OpenSim.Framework.Communications.Caches
444 /// <param name="imageID"></param> 483 /// <param name="imageID"></param>
445 public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID) 484 public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID)
446 { 485 {
447 //Console.WriteLine("texture request for " + imageID.ToStringHyphenated()); 486 // Console.WriteLine("texture request for " + imageID.ToStringHyphenated());
448 //check to see if texture is in local cache, if not request from asset server 487 //check to see if texture is in local cache, if not request from asset server
488 if(!this.AvatarRecievedTextures.ContainsKey(userInfo.AgentId))
489 {
490 this.AvatarRecievedTextures.Add(userInfo.AgentId, new List<LLUUID>());
491 }
492 if(this.AvatarRecievedTextures[userInfo.AgentId].Contains(imageID))
493 {
494 //Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them");
495 return;
496 }
449 if (!this.Textures.ContainsKey(imageID)) 497 if (!this.Textures.ContainsKey(imageID))
450 { 498 {
451 if (!this.RequestedTextures.ContainsKey(imageID)) 499 if (!this.RequestedTextures.ContainsKey(imageID))
@@ -472,7 +520,8 @@ namespace OpenSim.Framework.Communications.Caches
472 if (imag.Data.LongLength > 600) 520 if (imag.Data.LongLength > 600)
473 { 521 {
474 //over 600 bytes so split up file 522 //over 600 bytes so split up file
475 req.NumPackets = 1 + (int)(imag.Data.Length - 600 + 999) / 1000; 523 req.NumPackets = 1 + (int)(imag.Data.Length - 600 ) / 1000;
524 //Console.WriteLine("texture is " + imag.Data.Length + " which we will send in " +req.NumPackets +" packets");
476 } 525 }
477 else 526 else
478 { 527 {
@@ -582,37 +631,22 @@ namespace OpenSim.Framework.Communications.Caches
582 public class TextureSender 631 public class TextureSender
583 { 632 {
584 public AssetRequest request; 633 public AssetRequest request;
585 public event DownloadComplete OnComplete; 634
586 Thread m_thread;
587 public TextureSender(AssetRequest req) 635 public TextureSender(AssetRequest req)
588 { 636 {
589 request = req; 637 request = req;
590 //Console.WriteLine("creating worker thread for texture " + req.ImageInfo.FullID.ToStringHyphenated()); 638
591 //Console.WriteLine("texture data length is " + req.ImageInfo.Data.Length);
592 // Console.WriteLine("in " + req.NumPackets + " packets");
593 //ThreadPool.QueueUserWorkItem(new WaitCallback(SendTexture), new object());
594
595 //need some sort of custom threadpool here, as using the .net one, overloads it and stops the handling of incoming packets etc
596 //but don't really want to create a thread for every texture download
597 m_thread = new Thread(new ThreadStart(SendTexture));
598 m_thread.IsBackground = true;
599 m_thread.Start();
600 } 639 }
601 640
602 public void SendTexture() 641 public bool SendTexture()
603 { 642 {
604 //Console.WriteLine("starting to send sending texture " + request.ImageInfo.FullID.ToStringHyphenated()); 643 SendPacket();
605 while (request.PacketCounter != request.NumPackets) 644
645 if ((request.PacketCounter > request.NumPackets) |(request.NumPackets ==1))
606 { 646 {
607 SendPacket(); 647 return true;
608 Thread.Sleep(500);
609 }
610
611 //Console.WriteLine("finished sending texture " + request.ImageInfo.FullID.ToStringHyphenated());
612 if (OnComplete != null)
613 {
614 OnComplete(this);
615 } 648 }
649 return false;
616 } 650 }
617 651
618 public void SendPacket() 652 public void SendPacket()
@@ -643,13 +677,14 @@ namespace OpenSim.Framework.Communications.Caches
643 { 677 {
644 //more than one packet so split file up 678 //more than one packet so split file up
645 ImageDataPacket im = new ImageDataPacket(); 679 ImageDataPacket im = new ImageDataPacket();
646 im.ImageID.Packets = (ushort)req.NumPackets; 680 im.ImageID.Packets = (ushort)(req.NumPackets);
647 im.ImageID.ID = req.ImageInfo.FullID; 681 im.ImageID.ID = req.ImageInfo.FullID;
648 im.ImageID.Size = (uint)req.ImageInfo.Data.Length; 682 im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
649 im.ImageData.Data = new byte[600]; 683 im.ImageData.Data = new byte[600];
650 Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600); 684 Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600);
651 im.ImageID.Codec = 2; 685 im.ImageID.Codec = 2;
652 req.RequestUser.OutPacket(im); 686 req.RequestUser.OutPacket(im);
687 //this.SaveAssetToFile("packetheader.dat", im.ImageData.Data);
653 req.PacketCounter++; 688 req.PacketCounter++;
654 //req.ImageInfo.last_used = time; 689 //req.ImageInfo.last_used = time;
655 //System.Console.WriteLine("sent first packet of texture: 690 //System.Console.WriteLine("sent first packet of texture:
@@ -658,23 +693,36 @@ namespace OpenSim.Framework.Communications.Caches
658 } 693 }
659 else 694 else
660 { 695 {
661 //Console.WriteLine("sending packet" + req.PacketCounter + "for " + req.ImageInfo.FullID.ToStringHyphenated()); 696 // Console.WriteLine("sending packet" + req.PacketCounter + "for " + req.ImageInfo.FullID.ToStringHyphenated());
662 //send imagepacket 697 //send imagepacket
663 //more than one packet so split file up 698 //more than one packet so split file up
664 ImagePacketPacket im = new ImagePacketPacket(); 699 ImagePacketPacket im = new ImagePacketPacket();
665 im.ImageID.Packet = (ushort)req.PacketCounter; 700 im.ImageID.Packet = (ushort)(req.PacketCounter);
666 im.ImageID.ID = req.ImageInfo.FullID; 701 im.ImageID.ID = req.ImageInfo.FullID;
667 int size = req.ImageInfo.Data.Length - 600 - 1000 * (req.PacketCounter - 1); 702 int size = req.ImageInfo.Data.Length - 600 - (1000 * (req.PacketCounter - 1));
668 if (size > 1000) size = 1000; 703 if (size > 1000) size = 1000;
669 im.ImageData.Data = new byte[size]; 704 im.ImageData.Data = new byte[size];
670 Array.Copy(req.ImageInfo.Data, 600 + 1000 * (req.PacketCounter - 1), im.ImageData.Data, 0, size); 705 Array.Copy(req.ImageInfo.Data, 600 + (1000 * (req.PacketCounter - 1)), im.ImageData.Data, 0, size);
671 req.RequestUser.OutPacket(im); 706 req.RequestUser.OutPacket(im);
707 //if (req.PacketCounter == req.NumPackets)
708 // {
709 // this.SaveAssetToFile("packet"+req.PacketCounter+".dat", im.ImageData.Data);
710 //}
672 req.PacketCounter++; 711 req.PacketCounter++;
673 //req.ImageInfo.last_used = time; 712 //req.ImageInfo.last_used = time;
674 //System.Console.WriteLine("sent a packet of texture: "+req.image_info.FullID); 713 //System.Console.WriteLine("sent a packet of texture: "+req.image_info.FullID);
675 } 714 }
676 715
677 } 716 }
717
718 private void SaveAssetToFile(string filename, byte[] data)
719 {
720 FileStream fs = File.Create(filename);
721 BinaryWriter bw = new BinaryWriter(fs);
722 bw.Write(data);
723 bw.Close();
724 fs.Close();
725 }
678 } 726 }
679 } 727 }
680} 728}