Merge branch 'master' of /home/opensim/var/repo/opensim

integration
BlueWall 2012-05-18 12:35:21 -04:00
commit 9cb242e24d
7 changed files with 116 additions and 64 deletions

View File

@ -109,10 +109,11 @@ namespace OpenSim.Region.ClientStack.Linden
"Comms", "Comms",
false, false,
"debug eq", "debug eq",
"debug eq [0|1]", "debug eq [0|1|2]",
"Turn on event queue debugging", "Turn on event queue debugging"
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n" + "<= 0 - turns off all event queue logging"
+ "debug eq 0 will turn off event queue debugging.", + ">= 1 - turns on outgoing event logging"
+ ">= 2 - turns on poll notification",
HandleDebugEq); HandleDebugEq);
} }
else else
@ -235,19 +236,19 @@ namespace OpenSim.Region.ClientStack.Linden
// ClientClosed(client.AgentId); // ClientClosed(client.AgentId);
// } // }
private void ClientClosed(UUID AgentID, Scene scene) private void ClientClosed(UUID agentID, Scene scene)
{ {
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); // m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
int count = 0; int count = 0;
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
{ {
Thread.Sleep(1000); Thread.Sleep(1000);
} }
lock (queues) lock (queues)
{ {
queues.Remove(AgentID); queues.Remove(agentID);
} }
List<UUID> removeitems = new List<UUID>(); List<UUID> removeitems = new List<UUID>();
@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
{ {
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); // m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
if (ky == AgentID) if (ky == agentID)
{ {
removeitems.Add(ky); removeitems.Add(ky);
} }
@ -267,7 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
m_AvatarQueueUUIDMapping.Remove(ky); m_AvatarQueueUUIDMapping.Remove(ky);
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/"); string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
} }
} }
@ -281,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
searchval = m_QueueUUIDAvatarMapping[ky]; searchval = m_QueueUUIDAvatarMapping[ky];
if (searchval == AgentID) if (searchval == agentID)
{ {
removeitems.Add(ky); removeitems.Add(ky);
} }
@ -305,6 +311,15 @@ namespace OpenSim.Region.ClientStack.Linden
//} //}
} }
/// <summary>
/// Generate an Event Queue Get handler path for the given eqg uuid.
/// </summary>
/// <param name='eqgUuid'></param>
private string GenerateEqgCapPath(UUID eqgUuid)
{
return string.Format("/CAPS/EQG/{0}/", eqgUuid);
}
public void OnRegisterCaps(UUID agentID, Caps caps) public void OnRegisterCaps(UUID agentID, Caps caps)
{ {
// Register an event queue for the client // Register an event queue for the client
@ -316,8 +331,7 @@ namespace OpenSim.Region.ClientStack.Linden
// Let's instantiate a Queue for this agent right now // Let's instantiate a Queue for this agent right now
TryGetQueue(agentID); TryGetQueue(agentID);
string capsBase = "/CAPS/EQG/"; UUID eventQueueGetUUID;
UUID EventQueueGetUUID = UUID.Zero;
lock (m_AvatarQueueUUIDMapping) lock (m_AvatarQueueUUIDMapping)
{ {
@ -325,37 +339,35 @@ namespace OpenSim.Region.ClientStack.Linden
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
{ {
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
} }
else else
{ {
EventQueueGetUUID = UUID.Random(); eventQueueGetUUID = UUID.Random();
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
} }
} }
lock (m_QueueUUIDAvatarMapping) lock (m_QueueUUIDAvatarMapping)
{ {
if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
} }
lock (m_AvatarQueueUUIDMapping) lock (m_AvatarQueueUUIDMapping)
{ {
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
} }
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
// Register this as a caps handler // Register this as a caps handler
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about // FIXME: Confusingly, we need to register separate as a capability so that the client is told about
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
// really it should be possible to directly register the poll handler as a capability. // really it should be possible to directly register the poll handler as a capability.
caps.RegisterHandler( caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
"EventQueueGet",
new RestHTTPHandler(
"POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
// delegate(Hashtable m_dhttpMethod) // delegate(Hashtable m_dhttpMethod)
// { // {
// return ProcessQueue(m_dhttpMethod, agentID, caps); // return ProcessQueue(m_dhttpMethod, agentID, caps);
@ -364,9 +376,13 @@ namespace OpenSim.Region.ClientStack.Linden
// This will persist this beyond the expiry of the caps handlers // This will persist this beyond the expiry of the caps handlers
// TODO: Add EventQueueGet name/description for diagnostics // TODO: Add EventQueueGet name/description for diagnostics
MainServer.Instance.AddPollServiceHTTPHandler( MainServer.Instance.AddPollServiceHTTPHandler(
capsBase + EventQueueGetUUID.ToString() + "/", eventQueueGetPath,
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
// m_log.DebugFormat(
// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
Random rnd = new Random(Environment.TickCount); Random rnd = new Random(Environment.TickCount);
lock (m_ids) lock (m_ids)
{ {
@ -388,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden
return false; return false;
} }
/// <summary>
/// Logs a debug line for an outbound event queue message if appropriate.
/// </summary>
/// <param name='element'>Element containing message</param>
private void LogOutboundDebugMessage(OSD element, UUID agentId)
{
if (element is OSDMap)
{
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"Eq OUT {0,-30} to {1,-20} {2,-20}",
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
}
}
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
{ {
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId); if (DebugLevel >= 2)
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
Queue<OSD> queue = TryGetQueue(pAgentId); Queue<OSD> queue = TryGetQueue(pAgentId);
OSD element; OSD element;
@ -414,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden
} }
else else
{ {
if (DebugLevel > 0 && element is OSDMap) if (DebugLevel > 0)
{ LogOutboundDebugMessage(element, pAgentId);
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
array.Add(element); array.Add(element);
@ -430,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
element = queue.Dequeue(); element = queue.Dequeue();
if (DebugLevel > 0 && element is OSDMap) if (DebugLevel > 0)
{ LogOutboundDebugMessage(element, pAgentId);
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
}
array.Add(element); array.Add(element);
thisID++; thisID++;

View File

@ -2646,7 +2646,8 @@ namespace OpenSim.Region.Framework.Scenes
if (sp == null) if (sp == null)
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
m_clientManager.Add(client); m_clientManager.Add(client);
SubscribeToClientEvents(client); SubscribeToClientEvents(client);
@ -3905,8 +3906,7 @@ namespace OpenSim.Region.Framework.Scenes
// XPTO: if this agent is not allowed here as root, always return false // XPTO: if this agent is not allowed here as root, always return false
// We have to wait until the viewer contacts this region after receiving EAC. // TODO: This check should probably be in QueryAccess().
// That calls AddNewClient, which finally creates the ScenePresence
ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
if (nearestParcel == null) if (nearestParcel == null)
{ {
@ -3917,14 +3917,8 @@ namespace OpenSim.Region.Framework.Scenes
return false; return false;
} }
int num = m_sceneGraph.GetNumberOfScenePresences(); // We have to wait until the viewer contacts this region after receiving EAC.
// That calls AddNewClient, which finally creates the ScenePresence
if (num >= RegionInfo.RegionSettings.AgentLimit)
{
if (!Permissions.IsAdministrator(cAgentData.AgentID))
return false;
}
ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
if (childAgentUpdate != null) if (childAgentUpdate != null)
@ -3968,14 +3962,28 @@ namespace OpenSim.Region.Framework.Scenes
return false; return false;
} }
/// <summary>
/// Poll until the requested ScenePresence appears or we timeout.
/// </summary>
/// <returns>The scene presence is found, else null.</returns>
/// <param name='agentID'></param>
protected virtual ScenePresence WaitGetScenePresence(UUID agentID) protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
{ {
int ntimes = 10; int ntimes = 10;
ScenePresence childAgentUpdate = null; ScenePresence sp = null;
while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
Thread.Sleep(1000); Thread.Sleep(1000);
return childAgentUpdate;
if (sp == null)
m_log.WarnFormat(
"[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
agentID, RegionInfo.RegionName);
// else
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
return sp;
} }
public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
@ -5177,13 +5185,22 @@ namespace OpenSim.Region.Framework.Scenes
// child agent creation, thereby emulating the SL behavior. // child agent creation, thereby emulating the SL behavior.
public bool QueryAccess(UUID agentID, Vector3 position, out string reason) public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
{ {
int num = m_sceneGraph.GetNumberOfScenePresences(); // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
// However, the long term fix is to make sure root agent count is always accurate.
m_sceneGraph.RecalculateStats();
int num = m_sceneGraph.GetRootAgentCount();
if (num >= RegionInfo.RegionSettings.AgentLimit) if (num >= RegionInfo.RegionSettings.AgentLimit)
{ {
if (!Permissions.IsAdministrator(agentID)) if (!Permissions.IsAdministrator(agentID))
{ {
reason = "The region is full"; reason = "The region is full";
m_log.DebugFormat(
"[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}",
agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit);
return false; return false;
} }
} }

View File

@ -779,11 +779,6 @@ namespace OpenSim.Region.Framework.Scenes
return m_scenePresenceArray; return m_scenePresenceArray;
} }
public int GetNumberOfScenePresences()
{
return m_scenePresenceArray.Count;
}
/// <summary> /// <summary>
/// Request a scene presence by UUID. Fast, indexed lookup. /// Request a scene presence by UUID. Fast, indexed lookup.
/// </summary> /// </summary>

View File

@ -1169,6 +1169,12 @@ namespace OpenSim.Region.Framework.Scenes
Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
m_callbackURI = null; m_callbackURI = null;
} }
// else
// {
// m_log.DebugFormat(
// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
// }
ValidateAndSendAppearanceAndAgentData(); ValidateAndSendAppearanceAndAgentData();
@ -2508,7 +2514,7 @@ namespace OpenSim.Region.Framework.Scenes
// If we are using the the cached appearance then send it out to everyone // If we are using the the cached appearance then send it out to everyone
if (cachedappearance) if (cachedappearance)
{ {
m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name);
// If the avatars baked textures are all in the cache, then we have a // If the avatars baked textures are all in the cache, then we have a
// complete appearance... send it out, if not, then we'll send it when // complete appearance... send it out, if not, then we'll send it when
@ -2970,7 +2976,7 @@ namespace OpenSim.Region.Framework.Scenes
public void ChildAgentDataUpdate(AgentData cAgentData) public void ChildAgentDataUpdate(AgentData cAgentData)
{ {
//m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
if (!IsChildAgent) if (!IsChildAgent)
return; return;
@ -3110,6 +3116,9 @@ namespace OpenSim.Region.Framework.Scenes
m_originRegionID = cAgent.RegionID; m_originRegionID = cAgent.RegionID;
m_callbackURI = cAgent.CallbackURI; m_callbackURI = cAgent.CallbackURI;
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
m_pos = cAgent.Position; m_pos = cAgent.Position;
m_velocity = cAgent.Velocity; m_velocity = cAgent.Velocity;

View File

@ -1261,14 +1261,20 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_requestedUpdateFrequency = ms; m_requestedUpdateFrequency = ms;
m_eventsubscription = ms; m_eventsubscription = ms;
CollisionEventsThisFrame.Clear();
// Don't clear collision event reporting here. This is called directly from scene code and so can lead
// to a race condition with the simulate loop
_parent_scene.AddCollisionEventReporting(this); _parent_scene.AddCollisionEventReporting(this);
} }
public override void UnSubscribeEvents() public override void UnSubscribeEvents()
{ {
CollisionEventsThisFrame.Clear(); CollisionEventsThisFrame.Clear();
_parent_scene.RemoveCollisionEventReporting(this);
// Don't clear collision event reporting here. This is called directly from scene code and so can lead
// to a race condition with the simulate loop
m_requestedUpdateFrequency = 0; m_requestedUpdateFrequency = 0;
m_eventsubscription = 0; m_eventsubscription = 0;
} }

View File

@ -29,6 +29,7 @@ using System;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using log4net; using log4net;
using log4net.Config;
using Nini.Config; using Nini.Config;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
@ -52,6 +53,8 @@ namespace pCampBot
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)
{ {
XmlConfigurator.Configure();
IConfig config = ParseConfig(args); IConfig config = ParseConfig(args);
if (config.Get("help") != null || config.Get("loginuri") == null) if (config.Get("help") != null || config.Get("loginuri") == null)
{ {

View File

@ -8,7 +8,7 @@
<log4net> <log4net>
<appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console"> <appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console">
<layout type="log4net.Layout.PatternLayout"> <layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{HH:mm:ss} - %message%newline" /> <conversionPattern value="%date{HH:mm:ss.fff} - %message%newline" />
</layout> </layout>
</appender> </appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender"> <appender name="LogFileAppender" type="log4net.Appender.FileAppender">