* 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.ThreadPoolClientBranch
parent
9a8c19d67b
commit
48e085c774
|
@ -49,8 +49,14 @@ namespace OpenSim.Region.Environment.Modules
|
|||
private Scene m_scene;
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
/// <summary>
|
||||
/// There is one queue for all textures waiting to be sent, regardless of the requesting user.
|
||||
/// </summary>
|
||||
private readonly BlockingQueue<TextureSender> m_queueSenders = new BlockingQueue<TextureSender>();
|
||||
|
||||
/// <summary>
|
||||
/// Each user has their own texture download queue.
|
||||
/// </summary>
|
||||
private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
|
||||
new Dictionary<LLUUID, UserTextureDownloadService>();
|
||||
|
||||
|
@ -80,13 +86,17 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup the texture service related objects for the removed presence.
|
||||
/// </summary>
|
||||
/// <param name="agentId"> </param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this user have a registered texture download service?
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <param name="textureService"></param>
|
||||
/// <returns>Always returns true, since a service is created if one does not already exist</returns>
|
||||
private bool TryGetUserTextureService(LLUUID userID, out UserTextureDownloadService textureService)
|
||||
{
|
||||
lock (m_userTextureServices)
|
||||
|
@ -133,6 +149,11 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the process of requesting a given texture.
|
||||
/// </summary>
|
||||
/// <param name="sender"> </param>
|
||||
/// <param name="e"></param>
|
||||
public void TextureRequest(Object sender, TextureRequestArgs e)
|
||||
{
|
||||
IClientAPI client = (IClientAPI) sender;
|
||||
|
@ -142,9 +163,11 @@ namespace OpenSim.Region.Environment.Modules
|
|||
textureService.HandleTextureRequest(client, e);
|
||||
m_scene.AddPendingDownloads(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry point for the thread dedicated to processing the texture queue.
|
||||
/// </summary>
|
||||
public void ProcessTextureSenders()
|
||||
{
|
||||
TextureSender sender = null;
|
||||
|
@ -179,11 +202,14 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the texture has finished sending.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
private void TextureSent(TextureSender sender)
|
||||
{
|
||||
sender.Sending = false;
|
||||
m_scene.AddPendingDownloads(-1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,36 +34,59 @@ using OpenSim.Framework.Console;
|
|||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public class TextureSender
|
||||
{
|
||||
private static readonly log4net.ILog m_log
|
||||
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Records the number of times texture send has been called.
|
||||
/// </summary>
|
||||
public int counter = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the texture asset to send.
|
||||
/// </summary>
|
||||
private AssetBase m_asset;
|
||||
public long DataPointer = 0;
|
||||
public int NumPackets = 0;
|
||||
public int PacketCounter = 0;
|
||||
|
||||
/// <summary>
|
||||
/// This is actually the number of extra packets required to send the texture data! We always assume
|
||||
/// at least one is required.
|
||||
/// </summary>
|
||||
private int NumPackets = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
|
||||
/// at the 600th byte (0th indexed).
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load up the texture data to send.
|
||||
/// </summary>
|
||||
/// <param name="asset">
|
||||
/// A <see cref="AssetBase"/>
|
||||
/// </param>
|
||||
public void TextureReceived(AssetBase asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
|
@ -79,6 +102,10 @@ namespace OpenSim.Region.Environment.Modules
|
|||
PacketCounter = (int) StartPacketNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a texture packet to the client.
|
||||
/// </summary>
|
||||
/// <returns>True if the last packet has been sent, false otherwise.</returns>
|
||||
public bool SendTexturePacket()
|
||||
{
|
||||
SendPacket();
|
||||
|
@ -91,6 +118,9 @@ namespace OpenSim.Region.Environment.Modules
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a texture packet to the client.
|
||||
/// </summary>
|
||||
private void SendPacket()
|
||||
{
|
||||
if (PacketCounter <= NumPackets)
|
||||
|
@ -148,6 +178,12 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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...
|
||||
/// </summary>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
private int CalculateNumPackets(int length)
|
||||
{
|
||||
int numPackets = 0;
|
||||
|
|
|
@ -35,13 +35,27 @@ using OpenSim.Region.Environment.Scenes;
|
|||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
public class UserTextureDownloadService
|
||||
{
|
||||
private static readonly log4net.ILog m_log
|
||||
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Holds texture senders before they have received the appropriate texture from the asset cache.
|
||||
/// </summary>
|
||||
private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>();
|
||||
|
||||
/// <summary>
|
||||
/// Texture Senders are placed in this queue once they have received their texture from the asset
|
||||
/// cache. Another module actually invokes the send.
|
||||
/// </summary>
|
||||
private readonly BlockingQueue<TextureSender> m_sharedSendersQueue;
|
||||
|
||||
private readonly Scene m_scene;
|
||||
|
||||
public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue)
|
||||
|
@ -50,6 +64,12 @@ namespace OpenSim.Region.Environment.Modules
|
|||
m_sharedSendersQueue = sharedQueue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a texture request. This involves creating a texture sender and placing it on the
|
||||
/// previously passed in shared queue.
|
||||
/// </summary>
|
||||
/// <param name="client"> </param>
|
||||
/// <param name="e"></param>
|
||||
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
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The callback for the asset cache when a texture has been retrieved. This method queues the
|
||||
/// texture sender for processing.
|
||||
/// </summary>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="asset"></param>
|
||||
public void TextureCallback(LLUUID textureID, AssetBase asset)
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
|
@ -115,6 +142,10 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Place a ready texture sender on the processing queue.
|
||||
/// </summary>
|
||||
/// <param name="textureSender"></param>
|
||||
private void EnqueueTextureSender(TextureSender textureSender)
|
||||
{
|
||||
textureSender.Cancel = false;
|
||||
|
@ -127,6 +158,9 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close this module.
|
||||
/// </summary>
|
||||
internal void Close()
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
|
|
Loading…
Reference in New Issue