From 4b4ee9807054bdb06d7b1c3e0a5205836aff4f3c Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Wed, 2 Jan 2008 09:07:11 +0000 Subject: [PATCH] * Trying to address TextureSender issues * The BlockingQueue exposes Contains so we can make sure we don't add a TextureSender to the queue if there's already one present * introduced some TryGetValue and various code convention stuff --- OpenSim/Framework/BlockingQueue.cs | 25 ++++--- .../Communications/Cache/AssetCache.cs | 6 +- .../Communications/Cache/AssetServerBase.cs | 38 +++++----- .../Communications/Cache/SQLAssetServer.cs | 20 ++--- OpenSim/Region/ClientStack/ClientView.cs | 5 -- .../Modules/TextureDownloadModule.cs | 75 +++++++++++-------- 6 files changed, 91 insertions(+), 78 deletions(-) diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index ae2a189045..3ff3dac596 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs @@ -32,27 +32,34 @@ namespace OpenSim.Framework { public class BlockingQueue { - private Queue _queue = new Queue(); - private object _queueSync = new object(); + private readonly Queue m_queue = new Queue(); + private readonly object m_queueSync = new object(); public void Enqueue(T value) { - lock (_queueSync) + lock (m_queueSync) { - _queue.Enqueue(value); - Monitor.Pulse(_queueSync); + m_queue.Enqueue(value); + Monitor.Pulse(m_queueSync); } } public T Dequeue() { - lock (_queueSync) + lock (m_queueSync) { - if (_queue.Count < 1) - Monitor.Wait(_queueSync); + if (m_queue.Count < 1) + { + Monitor.Wait(m_queueSync); + } - return _queue.Dequeue(); + return m_queue.Dequeue(); } } + + public bool Contains(T item) + { + return m_queue.Contains(item); + } } } \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index 664625e4b6..bd3437bde7 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs @@ -56,10 +56,10 @@ namespace OpenSim.Framework.Communications.Cache public Dictionary RequestLists = new Dictionary(); - private IAssetServer m_assetServer; + private readonly IAssetServer m_assetServer; - private Thread m_assetCacheThread; - private LogBase m_log; + private readonly Thread m_assetCacheThread; + private readonly LogBase m_log; /// /// diff --git a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs index 318082b699..f0ed9684bb 100644 --- a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs +++ b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs @@ -37,11 +37,11 @@ namespace OpenSim.Framework.Communications.Cache { public abstract class AssetServerBase : IAssetServer { - protected IAssetReceiver _receiver; - protected BlockingQueue _assetRequests; - protected Thread _localAssetServerThread; - protected IAssetProvider m_assetProviderPlugin; - protected object syncLock = new object(); + protected IAssetReceiver m_receiver; + protected BlockingQueue m_assetRequests; + protected Thread m_localAssetServerThread; + protected IAssetProvider m_assetProvider; + protected object m_syncLock = new object(); // Temporarily hardcoded - should be a plugin protected IAssetLoader assetLoader = new AssetLoaderFileSystem(); @@ -71,14 +71,14 @@ namespace OpenSim.Framework.Communications.Cache MainLog.Instance.Verbose( "ASSET", "Asset {0} received from asset server", req.AssetID); - _receiver.AssetReceived(asset, req.IsTexture); + m_receiver.AssetReceived(asset, req.IsTexture); } else { MainLog.Instance.Error( "ASSET", "Asset {0} not found by asset server", req.AssetID); - _receiver.AssetNotFound(req.AssetID); + m_receiver.AssetNotFound(req.AssetID); } } @@ -95,11 +95,11 @@ namespace OpenSim.Framework.Communications.Cache public AssetServerBase() { MainLog.Instance.Verbose("ASSETSERVER", "Starting asset storage system"); - _assetRequests = new BlockingQueue(); + m_assetRequests = new BlockingQueue(); - _localAssetServerThread = new Thread(RunRequests); - _localAssetServerThread.IsBackground = true; - _localAssetServerThread.Start(); + m_localAssetServerThread = new Thread(RunRequests); + m_localAssetServerThread.IsBackground = true; + m_localAssetServerThread.Start(); } private void RunRequests() @@ -108,7 +108,7 @@ namespace OpenSim.Framework.Communications.Cache { try { - AssetRequest req = _assetRequests.Dequeue(); + AssetRequest req = m_assetRequests.Dequeue(); ProcessRequest(req); } @@ -121,7 +121,7 @@ namespace OpenSim.Framework.Communications.Cache public void SetReceiver(IAssetReceiver receiver) { - _receiver = receiver; + m_receiver = receiver; } public void RequestAsset(LLUUID assetID, bool isTexture) @@ -129,23 +129,23 @@ namespace OpenSim.Framework.Communications.Cache AssetRequest req = new AssetRequest(); req.AssetID = assetID; req.IsTexture = isTexture; - _assetRequests.Enqueue(req); + m_assetRequests.Enqueue(req); MainLog.Instance.Verbose("ASSET", "Added {0} to request queue", assetID); } public virtual void UpdateAsset(AssetBase asset) { - lock (syncLock) + lock (m_syncLock) { - m_assetProviderPlugin.UpdateAsset(asset); - m_assetProviderPlugin.CommitAssets(); + m_assetProvider.UpdateAsset(asset); + m_assetProvider.CommitAssets(); } } public void StoreAndCommitAsset(AssetBase asset) { - lock (syncLock) + lock (m_syncLock) { StoreAsset(asset); CommitAssets(); @@ -154,7 +154,7 @@ namespace OpenSim.Framework.Communications.Cache public virtual void Close() { - _localAssetServerThread.Abort(); + m_localAssetServerThread.Abort(); } public void SetServerInfo(string ServerUrl, string ServerKey) diff --git a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs index e4c278f716..0a141c3629 100644 --- a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs +++ b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs @@ -40,7 +40,7 @@ namespace OpenSim.Framework.Communications.Cache public SQLAssetServer(IAssetProvider assetProvider) { - m_assetProviderPlugin = assetProvider; + m_assetProvider = assetProvider; } public void AddPlugin(string FileName) @@ -58,12 +58,12 @@ namespace OpenSim.Framework.Communications.Cache { IAssetProvider plug = (IAssetProvider) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); - m_assetProviderPlugin = plug; - m_assetProviderPlugin.Initialise(); + m_assetProvider = plug; + m_assetProvider.Initialise(); MainLog.Instance.Verbose("AssetStorage", - "Added " + m_assetProviderPlugin.Name + " " + - m_assetProviderPlugin.Version); + "Added " + m_assetProvider.Name + " " + + m_assetProvider.Version); } } } @@ -74,15 +74,15 @@ namespace OpenSim.Framework.Communications.Cache { base.Close(); - m_assetProviderPlugin.CommitAssets(); + m_assetProvider.CommitAssets(); } protected override AssetBase GetAsset(AssetRequest req) { AssetBase asset; - lock (syncLock) + lock (m_syncLock) { - asset = m_assetProviderPlugin.FetchAsset(req.AssetID); + asset = m_assetProvider.FetchAsset(req.AssetID); } return asset; @@ -90,12 +90,12 @@ namespace OpenSim.Framework.Communications.Cache protected override void StoreAsset(AssetBase asset) { - m_assetProviderPlugin.CreateAsset(asset); + m_assetProvider.CreateAsset(asset); } protected override void CommitAssets() { - m_assetProviderPlugin.CommitAssets(); + m_assetProvider.CommitAssets(); } } } \ No newline at end of file diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 414916cbbe..066efef547 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -2973,7 +2973,6 @@ namespace OpenSim.Region.ClientStack //Console.WriteLine("image request: " + Pack.ToString()); for (int i = 0; i < imageRequest.RequestImage.Length; i++) { - // still working on the Texture download module so for now using old method if (OnRequestTexture != null) { TextureRequestArgs args = new TextureRequestArgs(); @@ -2984,10 +2983,6 @@ namespace OpenSim.Region.ClientStack OnRequestTexture(this, args); } - - // m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image, - // imageRequest.RequestImage[i].Packet, - // imageRequest.RequestImage[i].DiscardLevel); } break; case PacketType.TransferRequest: diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index 813be8d9a1..6d5d5e8568 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.Environment.Modules private Scene m_scene; private List m_scenes = new List(); - private BlockingQueue QueueSenders = new BlockingQueue(); + private readonly BlockingQueue m_queueSenders = new BlockingQueue(); private Dictionary m_userTextureServices = new Dictionary(); @@ -108,7 +108,7 @@ namespace OpenSim.Region.Environment.Modules return true; } - textureService = new UserTextureDownloadService(m_scene, QueueSenders); + textureService = new UserTextureDownloadService(m_scene, m_queueSenders); m_userTextureServices.Add(userID, textureService); return true; } @@ -128,7 +128,7 @@ namespace OpenSim.Region.Environment.Modules { while (true) { - TextureSender sender = QueueSenders.Dequeue(); + TextureSender sender = m_queueSenders.Dequeue(); if (sender.Cancel) { TextureSent(sender); @@ -142,7 +142,7 @@ namespace OpenSim.Region.Environment.Modules } else { - QueueSenders.Enqueue(sender); + m_queueSenders.Enqueue(sender); } } } @@ -155,11 +155,9 @@ namespace OpenSim.Region.Environment.Modules public class UserTextureDownloadService { - private Dictionary m_textureSenders = new Dictionary(); - - private BlockingQueue m_sharedSendersQueue; - - private Scene m_scene; + private readonly Dictionary m_textureSenders = new Dictionary(); + private readonly BlockingQueue m_sharedSendersQueue; + private readonly Scene m_scene; public UserTextureDownloadService(Scene scene, BlockingQueue sharedQueue) { @@ -169,38 +167,45 @@ namespace OpenSim.Region.Environment.Modules public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e) { + TextureSender textureSender; + //TODO: should be working out the data size/ number of packets to be sent for each discard level if ((e.DiscardLevel >= 0) || (e.Priority != 0)) { lock (m_textureSenders) { - if (!m_textureSenders.ContainsKey(e.RequestedAssetID)) + if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) + { + textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); + textureSender.counter = 0; + + if ((textureSender.ImageLoaded) && + (textureSender.Sending == false)) + { + textureSender.Sending = true; + + if (!m_sharedSendersQueue.Contains(textureSender)) + { + m_sharedSendersQueue.Enqueue(textureSender); + } + } + } + else { TextureSender requestHandler = new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber); m_textureSenders.Add(e.RequestedAssetID, requestHandler); m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); } - else - { - m_textureSenders[e.RequestedAssetID].UpdateRequest(e.DiscardLevel, e.PacketNumber); - m_textureSenders[e.RequestedAssetID].counter = 0; - if ((m_textureSenders[e.RequestedAssetID].ImageLoaded) && - (m_textureSenders[e.RequestedAssetID].Sending == false)) - { - m_textureSenders[e.RequestedAssetID].Sending = true; - m_sharedSendersQueue.Enqueue(m_textureSenders[e.RequestedAssetID]); - } - } } } else { lock (m_textureSenders) { - if (m_textureSenders.ContainsKey(e.RequestedAssetID)) + if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) { - m_textureSenders[e.RequestedAssetID].Cancel = true; + textureSender.Cancel = true; } } } @@ -210,19 +215,25 @@ namespace OpenSim.Region.Environment.Modules { lock (m_textureSenders) { - if (m_textureSenders.ContainsKey(textureID)) + TextureSender textureSender; + + if (m_textureSenders.TryGetValue(textureID, out textureSender)) { - if (!m_textureSenders[textureID].ImageLoaded) + if (!textureSender.ImageLoaded) { - m_textureSenders[textureID].TextureReceived(asset); - m_textureSenders[textureID].Sending = true; - m_textureSenders[textureID].counter = 0; - m_sharedSendersQueue.Enqueue(m_textureSenders[textureID]); + textureSender.TextureReceived(asset); + textureSender.Sending = true; + textureSender.counter = 0; + + if (!m_sharedSendersQueue.Contains(textureSender)) + { + m_sharedSendersQueue.Enqueue(textureSender); + } } } else { - // Got a texture with no sender object to handle it, this shouldn't happen + throw new Exception("Got a texture with no sender object to handle it, this shouldn't happen"); } } } @@ -329,9 +340,9 @@ namespace OpenSim.Region.Environment.Modules } catch (ArgumentOutOfRangeException) { - MainLog.Instance.Warn("TEXTURE", + MainLog.Instance.Error("TEXTURE", "Unable to separate texture into multiple packets: Array bounds failure on asset:" + - m_asset.FullID.ToString() + "- TextureDownloadModule.cs. line:328"); + m_asset.FullID.ToString() ); return; } RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);