diff options
author | MW | 2007-12-10 13:27:23 +0000 |
---|---|---|
committer | MW | 2007-12-10 13:27:23 +0000 |
commit | 611327e1040fa706665c543f67f9331a7e0136c5 (patch) | |
tree | 4426a50291dbc1c7c4ec065fd5c48921a767b658 /OpenSim/Framework/Communications/Cache/AssetCache.cs | |
parent | added musings on llInstantMessage (diff) | |
download | opensim-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.cs | 303 |
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 | ||
37 | namespace OpenSim.Framework.Communications.Cache | 37 | namespace 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 | } |