From 48e085c77451643cb7d819fc8c743a863b645a40 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Tue, 19 Feb 2008 23:42:30 +0000 Subject: * Add documentation * The reason why pending downloads tick ever upwards is because missing assets are never signalled to the TextureSender * Rectifying this is not straightfoward, but this will constitute the next patch. * This does not explain the memory leak. --- .../Environment/Modules/TextureDownloadModule.cs | 34 +++++++++++-- .../Region/Environment/Modules/TextureSender.cs | 58 ++++++++++++++++++---- .../Modules/UserTextureDownloadService.cs | 36 +++++++++++++- 3 files changed, 112 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index ff2d418..5d22e2a 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs @@ -49,8 +49,14 @@ namespace OpenSim.Region.Environment.Modules private Scene m_scene; private List m_scenes = new List(); + /// + /// There is one queue for all textures waiting to be sent, regardless of the requesting user. + /// private readonly BlockingQueue m_queueSenders = new BlockingQueue(); + /// + /// Each user has their own texture download queue. + /// private readonly Dictionary m_userTextureServices = new Dictionary(); @@ -80,13 +86,17 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// Cleanup the texture service related objects for the removed presence. + /// + /// private void EventManager_OnRemovePresence(LLUUID agentId) { UserTextureDownloadService textureService; lock (m_userTextureServices) { - if( m_userTextureServices.TryGetValue( agentId, out textureService )) + if (m_userTextureServices.TryGetValue(agentId, out textureService)) { textureService.Close(); @@ -118,6 +128,12 @@ namespace OpenSim.Region.Environment.Modules client.OnRequestTexture += TextureRequest; } + /// + /// Does this user have a registered texture download service? + /// + /// + /// + /// Always returns true, since a service is created if one does not already exist private bool TryGetUserTextureService(LLUUID userID, out UserTextureDownloadService textureService) { lock (m_userTextureServices) @@ -133,6 +149,11 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// Start the process of requesting a given texture. + /// + /// + /// public void TextureRequest(Object sender, TextureRequestArgs e) { IClientAPI client = (IClientAPI) sender; @@ -141,10 +162,12 @@ namespace OpenSim.Region.Environment.Modules { textureService.HandleTextureRequest(client, e); m_scene.AddPendingDownloads(1); - } - + } } + /// + /// Entry point for the thread dedicated to processing the texture queue. + /// public void ProcessTextureSenders() { TextureSender sender = null; @@ -179,11 +202,14 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// Called when the texture has finished sending. + /// + /// private void TextureSent(TextureSender sender) { sender.Sending = false; m_scene.AddPendingDownloads(-1); } - } } diff --git a/OpenSim/Region/Environment/Modules/TextureSender.cs b/OpenSim/Region/Environment/Modules/TextureSender.cs index 08da591..f2b3173 100644 --- a/OpenSim/Region/Environment/Modules/TextureSender.cs +++ b/OpenSim/Region/Environment/Modules/TextureSender.cs @@ -34,36 +34,59 @@ using OpenSim.Framework.Console; namespace OpenSim.Region.Environment.Modules { + /// + /// A TextureSender handles the process of receiving a texture requested by the client from the + /// AssetCache, and then sending that texture back to the client. + /// public class TextureSender { private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Records the number of times texture send has been called. + /// public int counter = 0; + + /// + /// Holds the texture asset to send. + /// private AssetBase m_asset; - public long DataPointer = 0; - public int NumPackets = 0; - public int PacketCounter = 0; + + /// + /// This is actually the number of extra packets required to send the texture data! We always assume + /// at least one is required. + /// + private int NumPackets = 0; + + /// + /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts + /// at the 600th byte (0th indexed). + /// + private int PacketCounter = 0; + public bool Cancel = false; public bool ImageLoaded = false; - public bool Sending = false; - public IClientAPI RequestUser; - public LLUUID RequestedAssetID; - public int RequestedDiscardLevel = -1; - public uint StartPacketNumber = 0; + private IClientAPI RequestUser; - // private int m_sentDiscardLevel = -1; + private int RequestedDiscardLevel = -1; + private uint StartPacketNumber = 0; - public TextureSender(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber) + public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) { RequestUser = client; - RequestedAssetID = textureID; RequestedDiscardLevel = discardLevel; StartPacketNumber = packetNumber; } + /// + /// Load up the texture data to send. + /// + /// + /// A + /// public void TextureReceived(AssetBase asset) { m_asset = asset; @@ -79,6 +102,10 @@ namespace OpenSim.Region.Environment.Modules PacketCounter = (int) StartPacketNumber; } + /// + /// Send a texture packet to the client. + /// + /// True if the last packet has been sent, false otherwise. public bool SendTexturePacket() { SendPacket(); @@ -91,6 +118,9 @@ namespace OpenSim.Region.Environment.Modules return false; } + /// + /// Sends a texture packet to the client. + /// private void SendPacket() { if (PacketCounter <= NumPackets) @@ -148,6 +178,12 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// Calculate the number of packets that will be required to send the texture loaded into this sender + /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... + /// + /// + /// private int CalculateNumPackets(int length) { int numPackets = 0; diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs index 32bc7c3..4a94266 100644 --- a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs +++ b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs @@ -35,13 +35,27 @@ using OpenSim.Region.Environment.Scenes; namespace OpenSim.Region.Environment.Modules { + /// + /// This module sets up texture senders in response to client texture requests, and places them on a + /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the + /// asset cache). + /// public class UserTextureDownloadService { private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Holds texture senders before they have received the appropriate texture from the asset cache. + /// private readonly Dictionary m_textureSenders = new Dictionary(); + + /// + /// Texture Senders are placed in this queue once they have received their texture from the asset + /// cache. Another module actually invokes the send. + /// private readonly BlockingQueue m_sharedSendersQueue; + private readonly Scene m_scene; public UserTextureDownloadService(Scene scene, BlockingQueue sharedQueue) @@ -50,6 +64,12 @@ namespace OpenSim.Region.Environment.Modules m_sharedSendersQueue = sharedQueue; } + /// + /// Handle a texture request. This involves creating a texture sender and placing it on the + /// previously passed in shared queue. + /// + /// + /// public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e) { TextureSender textureSender; @@ -72,8 +92,9 @@ namespace OpenSim.Region.Environment.Modules else { TextureSender requestHandler = - new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber); + new TextureSender(client, e.DiscardLevel, e.PacketNumber); m_textureSenders.Add(e.RequestedAssetID, requestHandler); + m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); } } @@ -90,6 +111,12 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// The callback for the asset cache when a texture has been retrieved. This method queues the + /// texture sender for processing. + /// + /// + /// public void TextureCallback(LLUUID textureID, AssetBase asset) { lock (m_textureSenders) @@ -115,6 +142,10 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// Place a ready texture sender on the processing queue. + /// + /// private void EnqueueTextureSender(TextureSender textureSender) { textureSender.Cancel = false; @@ -127,6 +158,9 @@ namespace OpenSim.Region.Environment.Modules } } + /// + /// Close this module. + /// internal void Close() { lock (m_textureSenders) -- cgit v1.1