* 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 stuffafrisby
parent
e678056e13
commit
4b4ee98070
|
@ -32,27 +32,34 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class BlockingQueue<T>
|
public class BlockingQueue<T>
|
||||||
{
|
{
|
||||||
private Queue<T> _queue = new Queue<T>();
|
private readonly Queue<T> m_queue = new Queue<T>();
|
||||||
private object _queueSync = new object();
|
private readonly object m_queueSync = new object();
|
||||||
|
|
||||||
public void Enqueue(T value)
|
public void Enqueue(T value)
|
||||||
{
|
{
|
||||||
lock (_queueSync)
|
lock (m_queueSync)
|
||||||
{
|
{
|
||||||
_queue.Enqueue(value);
|
m_queue.Enqueue(value);
|
||||||
Monitor.Pulse(_queueSync);
|
Monitor.Pulse(m_queueSync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Dequeue()
|
public T Dequeue()
|
||||||
{
|
{
|
||||||
lock (_queueSync)
|
lock (m_queueSync)
|
||||||
{
|
{
|
||||||
if (_queue.Count < 1)
|
if (m_queue.Count < 1)
|
||||||
Monitor.Wait(_queueSync);
|
{
|
||||||
|
Monitor.Wait(m_queueSync);
|
||||||
|
}
|
||||||
|
|
||||||
return _queue.Dequeue();
|
return m_queue.Dequeue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Contains(T item)
|
||||||
|
{
|
||||||
|
return m_queue.Contains(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,10 +56,10 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>();
|
public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>();
|
||||||
|
|
||||||
private IAssetServer m_assetServer;
|
private readonly IAssetServer m_assetServer;
|
||||||
|
|
||||||
private Thread m_assetCacheThread;
|
private readonly Thread m_assetCacheThread;
|
||||||
private LogBase m_log;
|
private readonly LogBase m_log;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|
|
@ -37,11 +37,11 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
public abstract class AssetServerBase : IAssetServer
|
public abstract class AssetServerBase : IAssetServer
|
||||||
{
|
{
|
||||||
protected IAssetReceiver _receiver;
|
protected IAssetReceiver m_receiver;
|
||||||
protected BlockingQueue<AssetRequest> _assetRequests;
|
protected BlockingQueue<AssetRequest> m_assetRequests;
|
||||||
protected Thread _localAssetServerThread;
|
protected Thread m_localAssetServerThread;
|
||||||
protected IAssetProvider m_assetProviderPlugin;
|
protected IAssetProvider m_assetProvider;
|
||||||
protected object syncLock = new object();
|
protected object m_syncLock = new object();
|
||||||
|
|
||||||
// Temporarily hardcoded - should be a plugin
|
// Temporarily hardcoded - should be a plugin
|
||||||
protected IAssetLoader assetLoader = new AssetLoaderFileSystem();
|
protected IAssetLoader assetLoader = new AssetLoaderFileSystem();
|
||||||
|
@ -71,14 +71,14 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
MainLog.Instance.Verbose(
|
MainLog.Instance.Verbose(
|
||||||
"ASSET", "Asset {0} received from asset server", req.AssetID);
|
"ASSET", "Asset {0} received from asset server", req.AssetID);
|
||||||
|
|
||||||
_receiver.AssetReceived(asset, req.IsTexture);
|
m_receiver.AssetReceived(asset, req.IsTexture);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainLog.Instance.Error(
|
MainLog.Instance.Error(
|
||||||
"ASSET", "Asset {0} not found by asset server", req.AssetID);
|
"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()
|
public AssetServerBase()
|
||||||
{
|
{
|
||||||
MainLog.Instance.Verbose("ASSETSERVER", "Starting asset storage system");
|
MainLog.Instance.Verbose("ASSETSERVER", "Starting asset storage system");
|
||||||
_assetRequests = new BlockingQueue<AssetRequest>();
|
m_assetRequests = new BlockingQueue<AssetRequest>();
|
||||||
|
|
||||||
_localAssetServerThread = new Thread(RunRequests);
|
m_localAssetServerThread = new Thread(RunRequests);
|
||||||
_localAssetServerThread.IsBackground = true;
|
m_localAssetServerThread.IsBackground = true;
|
||||||
_localAssetServerThread.Start();
|
m_localAssetServerThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RunRequests()
|
private void RunRequests()
|
||||||
|
@ -108,7 +108,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AssetRequest req = _assetRequests.Dequeue();
|
AssetRequest req = m_assetRequests.Dequeue();
|
||||||
|
|
||||||
ProcessRequest(req);
|
ProcessRequest(req);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
public void SetReceiver(IAssetReceiver receiver)
|
public void SetReceiver(IAssetReceiver receiver)
|
||||||
{
|
{
|
||||||
_receiver = receiver;
|
m_receiver = receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestAsset(LLUUID assetID, bool isTexture)
|
public void RequestAsset(LLUUID assetID, bool isTexture)
|
||||||
|
@ -129,23 +129,23 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
AssetRequest req = new AssetRequest();
|
AssetRequest req = new AssetRequest();
|
||||||
req.AssetID = assetID;
|
req.AssetID = assetID;
|
||||||
req.IsTexture = isTexture;
|
req.IsTexture = isTexture;
|
||||||
_assetRequests.Enqueue(req);
|
m_assetRequests.Enqueue(req);
|
||||||
|
|
||||||
MainLog.Instance.Verbose("ASSET", "Added {0} to request queue", assetID);
|
MainLog.Instance.Verbose("ASSET", "Added {0} to request queue", assetID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UpdateAsset(AssetBase asset)
|
public virtual void UpdateAsset(AssetBase asset)
|
||||||
{
|
{
|
||||||
lock (syncLock)
|
lock (m_syncLock)
|
||||||
{
|
{
|
||||||
m_assetProviderPlugin.UpdateAsset(asset);
|
m_assetProvider.UpdateAsset(asset);
|
||||||
m_assetProviderPlugin.CommitAssets();
|
m_assetProvider.CommitAssets();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StoreAndCommitAsset(AssetBase asset)
|
public void StoreAndCommitAsset(AssetBase asset)
|
||||||
{
|
{
|
||||||
lock (syncLock)
|
lock (m_syncLock)
|
||||||
{
|
{
|
||||||
StoreAsset(asset);
|
StoreAsset(asset);
|
||||||
CommitAssets();
|
CommitAssets();
|
||||||
|
@ -154,7 +154,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
public virtual void Close()
|
public virtual void Close()
|
||||||
{
|
{
|
||||||
_localAssetServerThread.Abort();
|
m_localAssetServerThread.Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetServerInfo(string ServerUrl, string ServerKey)
|
public void SetServerInfo(string ServerUrl, string ServerKey)
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
public SQLAssetServer(IAssetProvider assetProvider)
|
public SQLAssetServer(IAssetProvider assetProvider)
|
||||||
{
|
{
|
||||||
m_assetProviderPlugin = assetProvider;
|
m_assetProvider = assetProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPlugin(string FileName)
|
public void AddPlugin(string FileName)
|
||||||
|
@ -58,12 +58,12 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
IAssetProvider plug =
|
IAssetProvider plug =
|
||||||
(IAssetProvider) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
(IAssetProvider) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
||||||
m_assetProviderPlugin = plug;
|
m_assetProvider = plug;
|
||||||
m_assetProviderPlugin.Initialise();
|
m_assetProvider.Initialise();
|
||||||
|
|
||||||
MainLog.Instance.Verbose("AssetStorage",
|
MainLog.Instance.Verbose("AssetStorage",
|
||||||
"Added " + m_assetProviderPlugin.Name + " " +
|
"Added " + m_assetProvider.Name + " " +
|
||||||
m_assetProviderPlugin.Version);
|
m_assetProvider.Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,15 +74,15 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
{
|
{
|
||||||
base.Close();
|
base.Close();
|
||||||
|
|
||||||
m_assetProviderPlugin.CommitAssets();
|
m_assetProvider.CommitAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override AssetBase GetAsset(AssetRequest req)
|
protected override AssetBase GetAsset(AssetRequest req)
|
||||||
{
|
{
|
||||||
AssetBase asset;
|
AssetBase asset;
|
||||||
lock (syncLock)
|
lock (m_syncLock)
|
||||||
{
|
{
|
||||||
asset = m_assetProviderPlugin.FetchAsset(req.AssetID);
|
asset = m_assetProvider.FetchAsset(req.AssetID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return asset;
|
return asset;
|
||||||
|
@ -90,12 +90,12 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
protected override void StoreAsset(AssetBase asset)
|
protected override void StoreAsset(AssetBase asset)
|
||||||
{
|
{
|
||||||
m_assetProviderPlugin.CreateAsset(asset);
|
m_assetProvider.CreateAsset(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CommitAssets()
|
protected override void CommitAssets()
|
||||||
{
|
{
|
||||||
m_assetProviderPlugin.CommitAssets();
|
m_assetProvider.CommitAssets();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2973,7 +2973,6 @@ namespace OpenSim.Region.ClientStack
|
||||||
//Console.WriteLine("image request: " + Pack.ToString());
|
//Console.WriteLine("image request: " + Pack.ToString());
|
||||||
for (int i = 0; i < imageRequest.RequestImage.Length; i++)
|
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)
|
if (OnRequestTexture != null)
|
||||||
{
|
{
|
||||||
TextureRequestArgs args = new TextureRequestArgs();
|
TextureRequestArgs args = new TextureRequestArgs();
|
||||||
|
@ -2984,10 +2983,6 @@ namespace OpenSim.Region.ClientStack
|
||||||
|
|
||||||
OnRequestTexture(this, args);
|
OnRequestTexture(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image,
|
|
||||||
// imageRequest.RequestImage[i].Packet,
|
|
||||||
// imageRequest.RequestImage[i].DiscardLevel);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PacketType.TransferRequest:
|
case PacketType.TransferRequest:
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace OpenSim.Region.Environment.Modules
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private List<Scene> m_scenes = new List<Scene>();
|
private List<Scene> m_scenes = new List<Scene>();
|
||||||
|
|
||||||
private BlockingQueue<TextureSender> QueueSenders = new BlockingQueue<TextureSender>();
|
private readonly BlockingQueue<TextureSender> m_queueSenders = new BlockingQueue<TextureSender>();
|
||||||
|
|
||||||
private Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
|
private Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
|
||||||
new Dictionary<LLUUID, UserTextureDownloadService>();
|
new Dictionary<LLUUID, UserTextureDownloadService>();
|
||||||
|
@ -108,7 +108,7 @@ namespace OpenSim.Region.Environment.Modules
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
textureService = new UserTextureDownloadService(m_scene, QueueSenders);
|
textureService = new UserTextureDownloadService(m_scene, m_queueSenders);
|
||||||
m_userTextureServices.Add(userID, textureService);
|
m_userTextureServices.Add(userID, textureService);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ namespace OpenSim.Region.Environment.Modules
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
TextureSender sender = QueueSenders.Dequeue();
|
TextureSender sender = m_queueSenders.Dequeue();
|
||||||
if (sender.Cancel)
|
if (sender.Cancel)
|
||||||
{
|
{
|
||||||
TextureSent(sender);
|
TextureSent(sender);
|
||||||
|
@ -142,7 +142,7 @@ namespace OpenSim.Region.Environment.Modules
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QueueSenders.Enqueue(sender);
|
m_queueSenders.Enqueue(sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,11 +155,9 @@ namespace OpenSim.Region.Environment.Modules
|
||||||
|
|
||||||
public class UserTextureDownloadService
|
public class UserTextureDownloadService
|
||||||
{
|
{
|
||||||
private Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
|
private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
|
||||||
|
private readonly BlockingQueue<TextureSender> m_sharedSendersQueue;
|
||||||
private BlockingQueue<TextureSender> m_sharedSendersQueue;
|
private readonly Scene m_scene;
|
||||||
|
|
||||||
private Scene m_scene;
|
|
||||||
|
|
||||||
public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue)
|
public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue)
|
||||||
{
|
{
|
||||||
|
@ -169,38 +167,45 @@ namespace OpenSim.Region.Environment.Modules
|
||||||
|
|
||||||
public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e)
|
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
|
//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))
|
if ((e.DiscardLevel >= 0) || (e.Priority != 0))
|
||||||
{
|
{
|
||||||
lock (m_textureSenders)
|
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 =
|
TextureSender requestHandler =
|
||||||
new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber);
|
new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber);
|
||||||
m_textureSenders.Add(e.RequestedAssetID, requestHandler);
|
m_textureSenders.Add(e.RequestedAssetID, requestHandler);
|
||||||
m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback);
|
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
|
else
|
||||||
{
|
{
|
||||||
lock (m_textureSenders)
|
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)
|
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);
|
textureSender.TextureReceived(asset);
|
||||||
m_textureSenders[textureID].Sending = true;
|
textureSender.Sending = true;
|
||||||
m_textureSenders[textureID].counter = 0;
|
textureSender.counter = 0;
|
||||||
m_sharedSendersQueue.Enqueue(m_textureSenders[textureID]);
|
|
||||||
|
if (!m_sharedSendersQueue.Contains(textureSender))
|
||||||
|
{
|
||||||
|
m_sharedSendersQueue.Enqueue(textureSender);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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)
|
catch (ArgumentOutOfRangeException)
|
||||||
{
|
{
|
||||||
MainLog.Instance.Warn("TEXTURE",
|
MainLog.Instance.Error("TEXTURE",
|
||||||
"Unable to separate texture into multiple packets: Array bounds failure on asset:" +
|
"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;
|
return;
|
||||||
}
|
}
|
||||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||||
|
|
Loading…
Reference in New Issue