* Moves sending items to inventory via a delete into a seperate thread (this thread can be expanded to support all sends to inventory from inworld easily enough). Thread is temporary and only exists while items are being returned.

* This should remove the "lag" caused by deleting many objects.
* Patch brought to you by Joshua Nightshade's bitching at me to fix it.
0.6.0-stable
Adam Frisby 2008-07-06 02:27:10 +00:00
parent fd69251bcd
commit 55dda82180
1 changed files with 175 additions and 95 deletions

View File

@ -29,6 +29,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Timers;
using libsecondlife;
using libsecondlife.Packets;
using log4net;
@ -38,8 +39,20 @@ using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Scenes
{
class DeleteToInventoryHolder
{
public DeRezObjectPacket DeRezPacket;
public EntityBase selectedEnt;
public IClientAPI remoteClient;
public SceneObjectGroup objectGroup;
public LLUUID folderID;
}
public partial class Scene
{
private Timer m_inventoryTicker;
private readonly Queue<DeleteToInventoryHolder> m_inventoryDeletes = new Queue<DeleteToInventoryHolder>();
private static readonly ILog m_log
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -1395,7 +1408,7 @@ namespace OpenSim.Region.Environment.Scenes
/// Called when an object is removed from the environment into inventory.
/// </summary>
/// <param name="packet"></param>
/// <param name="simClient"></param>
/// <param name="remoteClient"></param>
public virtual void DeRezObject(Packet packet, IClientAPI remoteClient)
{
DeRezObjectPacket DeRezPacket = (DeRezObjectPacket) packet;
@ -1452,6 +1465,78 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectGroup objectGroup = (SceneObjectGroup)selectedEnt;
if (permissionToTake)
{
if (m_inventoryTicker != null)
{
m_inventoryTicker.Stop();
}
else
{
m_inventoryTicker = new Timer(2000);
m_inventoryTicker.AutoReset = false;
m_inventoryTicker.Elapsed += InventoryRunDeleteTimer;
}
lock(m_inventoryDeletes)
{
DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
dtis.DeRezPacket = DeRezPacket;
dtis.folderID = folderID;
dtis.objectGroup = objectGroup;
dtis.remoteClient = remoteClient;
dtis.selectedEnt = selectedEnt;
m_inventoryDeletes.Enqueue(dtis);
}
m_inventoryTicker.Start();
// Visually remove it, even if it isnt really gone yet.
objectGroup.FakeDeleteGroup();
}
else if (permissionToDelete)
{
DeleteSceneObject(objectGroup);
}
}
}
}
void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
{
m_log.Info("Starting inventory send loop");
while (InventoryDeQueueAndDelete() == true)
{
m_log.Info("Returned item successfully, continuing...");
}
}
private bool InventoryDeQueueAndDelete()
{
DeleteToInventoryHolder x;
try
{
lock (m_inventoryDeletes)
{
int left = m_inventoryDeletes.Count;
if (left > 0)
{
m_log.InfoFormat("Sending deleted object to user's inventory, {0} item(s) remaining.", left);
x = m_inventoryDeletes.Dequeue();
DeleteToInventory(x.DeRezPacket, x.selectedEnt, x.remoteClient, x.objectGroup, x.folderID);
return true;
}
}
} catch(Exception e)
{
m_log.Error(e.ToString());
}
m_log.Info("No objects left in inventory delete queue.");
return false;
}
private void DeleteToInventory(DeRezObjectPacket DeRezPacket, EntityBase selectedEnt, IClientAPI remoteClient, SceneObjectGroup objectGroup, LLUUID folderID)
{
string sceneObjectXml = objectGroup.ToXmlString();
@ -1555,15 +1640,10 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
}
if (permissionToDelete)
{
// Finally remove the item, for reals this time.
DeleteSceneObject(objectGroup);
}
}
}
}
public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID assetID, LLUUID agentID)
{