Merge branch 'master' into careminster
Conflicts: OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.csavinationmerge
commit
a7eb1b5b85
|
@ -64,7 +64,11 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public string CapsObjectPath { get { return m_capsObjectPath; } }
|
public string CapsObjectPath { get { return m_capsObjectPath; } }
|
||||||
|
|
||||||
private CapsHandlers m_capsHandlers;
|
private CapsHandlers m_capsHandlers;
|
||||||
private Dictionary<string, string> m_externalCapsHandlers;
|
|
||||||
|
private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
||||||
|
= new Dictionary<string, PollServiceEventArgs>();
|
||||||
|
|
||||||
|
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
||||||
|
|
||||||
private IHttpServer m_httpListener;
|
private IHttpServer m_httpListener;
|
||||||
private UUID m_agentID;
|
private UUID m_agentID;
|
||||||
|
@ -134,7 +138,6 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
m_agentID = agent;
|
m_agentID = agent;
|
||||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
||||||
m_externalCapsHandlers = new Dictionary<string, string>();
|
|
||||||
m_regionName = regionName;
|
m_regionName = regionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,6 +152,27 @@ namespace OpenSim.Framework.Capabilities
|
||||||
m_capsHandlers[capName] = handler;
|
m_capsHandlers[capName] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
||||||
|
{
|
||||||
|
m_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||||
|
|
||||||
|
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
|
||||||
|
|
||||||
|
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||||
|
// string protocol = "http";
|
||||||
|
// string hostName = m_httpListenerHostName;
|
||||||
|
//
|
||||||
|
// if (MainServer.Instance.UseSSL)
|
||||||
|
// {
|
||||||
|
// hostName = MainServer.Instance.SSLCommonName;
|
||||||
|
// port = MainServer.Instance.SSLPort;
|
||||||
|
// protocol = "https";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// RegisterHandler(
|
||||||
|
// capName, String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, pollServiceHandler.Url));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register an external handler. The service for this capability is somewhere else
|
/// Register an external handler. The service for this capability is somewhere else
|
||||||
/// given by the URL.
|
/// given by the URL.
|
||||||
|
@ -165,13 +189,70 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void DeregisterHandlers()
|
public void DeregisterHandlers()
|
||||||
{
|
{
|
||||||
if (m_capsHandlers != null)
|
foreach (string capsName in m_capsHandlers.Caps)
|
||||||
{
|
{
|
||||||
foreach (string capsName in m_capsHandlers.Caps)
|
m_capsHandlers.Remove(capsName);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
||||||
|
{
|
||||||
|
m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
||||||
|
{
|
||||||
|
return m_pollServiceHandlers.TryGetValue(name, out pollHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, PollServiceEventArgs> GetPollHandlers()
|
||||||
|
{
|
||||||
|
return new Dictionary<string, PollServiceEventArgs>(m_pollServiceHandlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return an LLSD-serializable Hashtable describing the
|
||||||
|
/// capabilities and their handler details.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
||||||
|
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
||||||
|
{
|
||||||
|
Hashtable caps = CapsHandlers.GetCapsDetails(excludeSeed, requestedCaps);
|
||||||
|
|
||||||
|
lock (m_pollServiceHandlers)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair <string, PollServiceEventArgs> kvp in m_pollServiceHandlers)
|
||||||
{
|
{
|
||||||
m_capsHandlers.Remove(capsName);
|
if (!requestedCaps.Contains(kvp.Key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string hostName = m_httpListenerHostName;
|
||||||
|
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||||
|
string protocol = "http";
|
||||||
|
|
||||||
|
if (MainServer.Instance.UseSSL)
|
||||||
|
{
|
||||||
|
hostName = MainServer.Instance.SSLCommonName;
|
||||||
|
port = MainServer.Instance.SSLPort;
|
||||||
|
protocol = "https";
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||||
|
|
||||||
|
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the external too
|
||||||
|
foreach (KeyValuePair<string, string> kvp in ExternalCapsHandlers)
|
||||||
|
{
|
||||||
|
if (!requestedCaps.Contains(kvp.Key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
caps[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate()
|
public void Activate()
|
||||||
|
|
|
@ -77,20 +77,34 @@ namespace OpenSim.Data.Null
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Environment Settings
|
#region Environment Settings
|
||||||
|
|
||||||
|
private Dictionary<UUID, string> EnvironmentSettings = new Dictionary<UUID, string>();
|
||||||
|
|
||||||
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||||
{
|
{
|
||||||
//This connector doesn't support the Environment module yet
|
lock (EnvironmentSettings)
|
||||||
|
{
|
||||||
|
if (EnvironmentSettings.ContainsKey(regionUUID))
|
||||||
|
return EnvironmentSettings[regionUUID];
|
||||||
|
}
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||||
{
|
{
|
||||||
//This connector doesn't support the Environment module yet
|
lock (EnvironmentSettings)
|
||||||
|
{
|
||||||
|
EnvironmentSettings[regionUUID] = settings;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||||
{
|
{
|
||||||
//This connector doesn't support the Environment module yet
|
lock (EnvironmentSettings)
|
||||||
|
{
|
||||||
|
if (EnvironmentSettings.ContainsKey(regionUUID))
|
||||||
|
EnvironmentSettings.Remove(regionUUID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
:VERSION 1 # --------------------------
|
:VERSION 2 # --------------------------
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
||||||
CREATE TABLE hg_traveling_data (
|
CREATE TABLE hg_traveling_data(
|
||||||
SessionID VARCHAR(36) NOT NULL,
|
SessionID VARCHAR(36) NOT NULL,
|
||||||
UserID VARCHAR(36) NOT NULL,
|
UserID VARCHAR(36) NOT NULL,
|
||||||
GridExternalName VARCHAR(255) NOT NULL DEFAULT '',
|
GridExternalName VARCHAR(255) NOT NULL DEFAULT "",
|
||||||
ServiceToken VARCHAR(255) NOT NULL DEFAULT '',
|
ServiceToken VARCHAR(255) NOT NULL DEFAULT "",
|
||||||
ClientIPAddress VARCHAR(16) NOT NULL DEFAULT '',
|
ClientIPAddress VARCHAR(16) NOT NULL DEFAULT "",
|
||||||
MyIPAddress VARCHAR(16) NOT NULL DEFAULT '',
|
MyIPAddress VARCHAR(16) NOT NULL DEFAULT "",
|
||||||
TMStamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
TMStamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`SessionID`),
|
PRIMARY KEY(SessionID),
|
||||||
KEY (`UserID`)
|
UNIQUE(UserID)
|
||||||
) ENGINE=InnoDB;
|
);
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
lock (m_queueSync)
|
lock (m_queueSync)
|
||||||
{
|
{
|
||||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
while (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||||
{
|
{
|
||||||
Monitor.Wait(m_queueSync);
|
Monitor.Wait(m_queueSync);
|
||||||
}
|
}
|
||||||
|
@ -76,9 +76,10 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
lock (m_queueSync)
|
lock (m_queueSync)
|
||||||
{
|
{
|
||||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
bool success = true;
|
||||||
|
while (m_queue.Count < 1 && m_pqueue.Count < 1 && success)
|
||||||
{
|
{
|
||||||
Monitor.Wait(m_queueSync, msTimeout);
|
success = Monitor.Wait(m_queueSync, msTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pqueue.Count > 0)
|
if (m_pqueue.Count > 0)
|
||||||
|
@ -89,8 +90,17 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicate whether this queue contains the given item.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||||
|
/// </remarks>
|
||||||
public bool Contains(T item)
|
public bool Contains(T item)
|
||||||
{
|
{
|
||||||
|
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
lock (m_queueSync)
|
lock (m_queueSync)
|
||||||
{
|
{
|
||||||
if (m_pqueue.Contains(item))
|
if (m_pqueue.Contains(item))
|
||||||
|
@ -99,16 +109,28 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a count of the number of requests on this queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||||
|
/// </remarks>
|
||||||
public int Count()
|
public int Count()
|
||||||
{
|
{
|
||||||
lock (m_queueSync)
|
return m_queue.Count + m_pqueue.Count;
|
||||||
{
|
|
||||||
return m_queue.Count+m_pqueue.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the array of items on this queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||||
|
/// </remarks>
|
||||||
public T[] GetQueueArray()
|
public T[] GetQueueArray()
|
||||||
{
|
{
|
||||||
|
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||||
|
return new T[0];
|
||||||
|
|
||||||
lock (m_queueSync)
|
lock (m_queueSync)
|
||||||
{
|
{
|
||||||
return m_queue.ToArray();
|
return m_queue.ToArray();
|
||||||
|
|
|
@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console
|
||||||
string uri = "/ReadResponses/" + sessionID.ToString() + "/";
|
string uri = "/ReadResponses/" + sessionID.ToString() + "/";
|
||||||
|
|
||||||
m_Server.AddPollServiceHTTPHandler(
|
m_Server.AddPollServiceHTTPHandler(
|
||||||
uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout
|
uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout
|
||||||
|
|
||||||
XmlDocument xmldoc = new XmlDocument();
|
XmlDocument xmldoc = new XmlDocument();
|
||||||
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
|
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
|
|
@ -387,6 +387,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs))
|
if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs))
|
||||||
{
|
{
|
||||||
|
psEvArgs.RequestsReceived++;
|
||||||
|
|
||||||
PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request);
|
PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request);
|
||||||
|
|
||||||
if (psEvArgs.Request != null)
|
if (psEvArgs.Request != null)
|
||||||
|
|
|
@ -50,25 +50,39 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
public enum EventType : int
|
public enum EventType : int
|
||||||
{
|
{
|
||||||
Normal = 0,
|
LongPoll = 0,
|
||||||
LslHttp = 1,
|
LslHttp = 1,
|
||||||
Inventory = 2,
|
Inventory = 2,
|
||||||
Texture = 3,
|
Texture = 3,
|
||||||
Mesh = 4
|
Mesh = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Url { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of requests received for this poll service.
|
||||||
|
/// </summary>
|
||||||
|
public int RequestsReceived { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of requests handled by this poll service.
|
||||||
|
/// </summary>
|
||||||
|
public int RequestsHandled { get; set; }
|
||||||
|
|
||||||
public PollServiceEventArgs(
|
public PollServiceEventArgs(
|
||||||
RequestMethod pRequest,
|
RequestMethod pRequest,
|
||||||
|
string pUrl,
|
||||||
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
|
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
|
||||||
UUID pId, int pTimeOutms)
|
UUID pId, int pTimeOutms)
|
||||||
{
|
{
|
||||||
Request = pRequest;
|
Request = pRequest;
|
||||||
|
Url = pUrl;
|
||||||
HasEvents = pHasEvents;
|
HasEvents = pHasEvents;
|
||||||
GetEvents = pGetEvents;
|
GetEvents = pGetEvents;
|
||||||
NoEvents = pNoEvents;
|
NoEvents = pNoEvents;
|
||||||
Id = pId;
|
Id = pId;
|
||||||
TimeOutms = pTimeOutms;
|
TimeOutms = pTimeOutms;
|
||||||
Type = EventType.Normal;
|
Type = EventType.LongPoll;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,13 +26,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using HttpServer;
|
using HttpServer;
|
||||||
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public class PollServiceHttpRequest
|
public class PollServiceHttpRequest
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public readonly PollServiceEventArgs PollServiceArgs;
|
public readonly PollServiceEventArgs PollServiceArgs;
|
||||||
public readonly IHttpClientContext HttpContext;
|
public readonly IHttpClientContext HttpContext;
|
||||||
public readonly IHttpRequest Request;
|
public readonly IHttpRequest Request;
|
||||||
|
@ -48,5 +54,44 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
RequestTime = System.Environment.TickCount;
|
RequestTime = System.Environment.TickCount;
|
||||||
RequestID = UUID.Random();
|
RequestID = UUID.Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata)
|
||||||
|
{
|
||||||
|
OSHttpResponse response
|
||||||
|
= new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext);
|
||||||
|
|
||||||
|
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
|
||||||
|
|
||||||
|
response.SendChunked = false;
|
||||||
|
response.ContentLength64 = buffer.Length;
|
||||||
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//response.OutputStream.Close();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.OutputStream.Flush();
|
||||||
|
response.Send();
|
||||||
|
|
||||||
|
//if (!response.KeepAlive && response.ReuseContext)
|
||||||
|
// response.FreeContext();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
PollServiceArgs.RequestsHandled++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -105,7 +105,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
if (m_running)
|
if (m_running)
|
||||||
{
|
{
|
||||||
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal)
|
if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll)
|
||||||
{
|
{
|
||||||
m_requests.Enqueue(req);
|
m_requests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (responsedata == null)
|
if (responsedata == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue
|
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -1791,10 +1791,12 @@ namespace OpenSim.Framework
|
||||||
FireAndForget(callback, null);
|
FireAndForget(callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InitThreadPool(int maxThreads)
|
public static void InitThreadPool(int minThreads, int maxThreads)
|
||||||
{
|
{
|
||||||
if (maxThreads < 2)
|
if (maxThreads < 2)
|
||||||
throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
|
throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
|
||||||
|
if (minThreads > maxThreads || minThreads < 2)
|
||||||
|
throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads");
|
||||||
if (m_ThreadPool != null)
|
if (m_ThreadPool != null)
|
||||||
throw new InvalidOperationException("SmartThreadPool is already initialized");
|
throw new InvalidOperationException("SmartThreadPool is already initialized");
|
||||||
|
|
||||||
|
@ -1802,7 +1804,7 @@ namespace OpenSim.Framework
|
||||||
startInfo.ThreadPoolName = "Util";
|
startInfo.ThreadPoolName = "Util";
|
||||||
startInfo.IdleTimeout = 2000;
|
startInfo.IdleTimeout = 2000;
|
||||||
startInfo.MaxWorkerThreads = maxThreads;
|
startInfo.MaxWorkerThreads = maxThreads;
|
||||||
startInfo.MinWorkerThreads = 2;
|
startInfo.MinWorkerThreads = minThreads;
|
||||||
|
|
||||||
m_ThreadPool = new SmartThreadPool(startInfo);
|
m_ThreadPool = new SmartThreadPool(startInfo);
|
||||||
}
|
}
|
||||||
|
@ -1877,7 +1879,7 @@ namespace OpenSim.Framework
|
||||||
break;
|
break;
|
||||||
case FireAndForgetMethod.SmartThreadPool:
|
case FireAndForgetMethod.SmartThreadPool:
|
||||||
if (m_ThreadPool == null)
|
if (m_ThreadPool == null)
|
||||||
InitThreadPool(15);
|
InitThreadPool(2, 15);
|
||||||
m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
|
m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
|
||||||
break;
|
break;
|
||||||
case FireAndForgetMethod.Thread:
|
case FireAndForgetMethod.Thread:
|
||||||
|
@ -2265,7 +2267,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
lock (m_syncRoot)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
m_lowQueue.Enqueue(data);
|
q.Enqueue(data);
|
||||||
m_s.WaitOne(0);
|
m_s.WaitOne(0);
|
||||||
m_s.Release();
|
m_s.Release();
|
||||||
}
|
}
|
||||||
|
@ -2305,7 +2307,7 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
if (m_highQueue.Count > 0)
|
if (m_highQueue.Count > 0)
|
||||||
res = m_highQueue.Dequeue();
|
res = m_highQueue.Dequeue();
|
||||||
else
|
else if (m_lowQueue.Count > 0)
|
||||||
res = m_lowQueue.Dequeue();
|
res = m_lowQueue.Dequeue();
|
||||||
|
|
||||||
if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
|
if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace OpenSim
|
||||||
IConfig startupConfig = Config.Configs["Startup"];
|
IConfig startupConfig = Config.Configs["Startup"];
|
||||||
IConfig networkConfig = Config.Configs["Network"];
|
IConfig networkConfig = Config.Configs["Network"];
|
||||||
|
|
||||||
|
int stpMinThreads = 2;
|
||||||
int stpMaxThreads = 15;
|
int stpMaxThreads = 15;
|
||||||
|
|
||||||
if (startupConfig != null)
|
if (startupConfig != null)
|
||||||
|
@ -112,12 +113,13 @@ namespace OpenSim
|
||||||
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
|
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
|
||||||
Util.FireAndForgetMethod = asyncCallMethod;
|
Util.FireAndForgetMethod = asyncCallMethod;
|
||||||
|
|
||||||
|
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15);
|
||||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
|
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
|
||||||
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
|
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||||
Util.InitThreadPool(stpMaxThreads);
|
Util.InitThreadPool(stpMinThreads, stpMaxThreads);
|
||||||
|
|
||||||
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
|
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
|
||||||
}
|
}
|
||||||
|
@ -423,8 +425,8 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
||||||
|
|
||||||
if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
|
if (presence.Firstname.ToLower().Equals(mainParams[2].ToLower()) &&
|
||||||
presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
|
presence.Lastname.ToLower().Equals(mainParams[3].ToLower()))
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output(
|
MainConsole.Instance.Output(
|
||||||
String.Format(
|
String.Format(
|
||||||
|
@ -438,6 +440,7 @@ namespace OpenSim
|
||||||
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
||||||
|
|
||||||
presence.Scene.IncomingCloseAgent(presence.UUID, force);
|
presence.Scene.IncomingCloseAgent(presence.UUID, force);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,18 +367,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
foreach (OSD c in capsRequested)
|
foreach (OSD c in capsRequested)
|
||||||
validCaps.Add(c.AsString());
|
validCaps.Add(c.AsString());
|
||||||
|
|
||||||
Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true, validCaps);
|
string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.GetCapsDetails(true, validCaps));
|
||||||
|
|
||||||
// Add the external too
|
|
||||||
foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
|
|
||||||
{
|
|
||||||
if (!validCaps.Contains(kvp.Key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
caps[kvp.Key] = kvp.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
string result = LLSDHelpers.SerialiseLLSDReply(caps);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
|
//m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
/// </value>
|
/// </value>
|
||||||
public int DebugLevel { get; set; }
|
public int DebugLevel { get; set; }
|
||||||
|
|
||||||
|
// Viewer post requests timeout in 60 secs
|
||||||
|
// https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44
|
||||||
|
//
|
||||||
|
private const int VIEWER_TIMEOUT = 60 * 1000;
|
||||||
|
// Just to be safe, we work on a 10 sec shorter cycle
|
||||||
|
private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
|
||||||
|
|
||||||
protected Scene m_scene;
|
protected Scene m_scene;
|
||||||
|
|
||||||
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
||||||
|
@ -252,29 +259,32 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
List<UUID> removeitems = new List<UUID>();
|
List<UUID> removeitems = new List<UUID>();
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
m_AvatarQueueUUIDMapping.Remove(agentID);
|
||||||
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
|
||||||
if (ky == agentID)
|
|
||||||
{
|
|
||||||
removeitems.Add(ky);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (UUID ky in removeitems)
|
// lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
// {
|
||||||
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
// foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
||||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
// {
|
||||||
|
//// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
||||||
string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
|
// if (ky == agentID)
|
||||||
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
|
// {
|
||||||
|
// removeitems.Add(ky);
|
||||||
// m_log.DebugFormat(
|
// }
|
||||||
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
|
// }
|
||||||
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
|
//
|
||||||
}
|
// foreach (UUID ky in removeitems)
|
||||||
}
|
// {
|
||||||
|
// UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||||
|
// m_AvatarQueueUUIDMapping.Remove(ky);
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
UUID searchval = UUID.Zero;
|
UUID searchval = UUID.Zero;
|
||||||
|
|
||||||
|
@ -359,29 +369,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
|
caps.RegisterPollHandler(
|
||||||
|
"EventQueueGet",
|
||||||
// Register this as a caps handler
|
new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
|
||||||
// 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
|
|
||||||
// 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.
|
|
||||||
caps.RegisterHandler(
|
|
||||||
"EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null, "EventQueueGet", null));
|
|
||||||
// delegate(Hashtable m_dhttpMethod)
|
|
||||||
// {
|
|
||||||
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
|
||||||
// }));
|
|
||||||
|
|
||||||
// This will persist this beyond the expiry of the caps handlers
|
|
||||||
// TODO: Add EventQueueGet name/description for diagnostics
|
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
|
||||||
eventQueueGetPath,
|
|
||||||
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 40000));
|
|
||||||
|
|
||||||
// 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)
|
||||||
|
@ -399,7 +389,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
Queue<OSD> queue = GetQueue(agentID);
|
Queue<OSD> queue = GetQueue(agentID);
|
||||||
if (queue != null)
|
if (queue != null)
|
||||||
lock (queue)
|
lock (queue)
|
||||||
|
{
|
||||||
|
//m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
|
||||||
return queue.Count > 0;
|
return queue.Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +415,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
public Hashtable GetEvents(UUID requestID, UUID pAgentId)
|
public Hashtable GetEvents(UUID requestID, UUID pAgentId)
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 2)
|
if (DebugLevel >= 2)
|
||||||
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
m_log.WarnFormat("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;
|
||||||
|
|
|
@ -246,8 +246,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private MeshCapsDataThrottler m_throttler;
|
private MeshCapsDataThrottler m_throttler;
|
||||||
public PollServiceMeshEventArgs(UUID pId, Scene scene) :
|
public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
|
||||||
base(null, null, null, null, pId, int.MaxValue)
|
base(null, uri, null, null, null, pId, int.MaxValue)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
|
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
|
||||||
|
@ -361,7 +361,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
||||||
|
|
||||||
// Register this as a poll service
|
// Register this as a poll service
|
||||||
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(agentID, m_scene);
|
PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
|
||||||
|
|
||||||
args.Type = PollServiceEventArgs.EventType.Mesh;
|
args.Type = PollServiceEventArgs.EventType.Mesh;
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||||
|
|
|
@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
|
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
|
||||||
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
|
public PollServiceTextureEventArgs(UUID pId, Scene scene) :
|
||||||
base(null, null, null, null, pId, int.MaxValue)
|
base(null, "", null, null, null, pId, int.MaxValue)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
// x is request id, y is userid
|
// x is request id, y is userid
|
||||||
|
|
|
@ -78,7 +78,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private static WebFetchInvDescHandler m_webFetchHandler;
|
private static WebFetchInvDescHandler m_webFetchHandler;
|
||||||
|
|
||||||
private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
|
|
||||||
private static Thread[] m_workerThreads = null;
|
private static Thread[] m_workerThreads = null;
|
||||||
|
|
||||||
private static DoubleQueue<aPollRequest> m_queue =
|
private static DoubleQueue<aPollRequest> m_queue =
|
||||||
|
@ -115,7 +114,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||||
m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
|
|
||||||
|
|
||||||
foreach (Thread t in m_workerThreads)
|
foreach (Thread t in m_workerThreads)
|
||||||
Watchdog.AbortThread(t.ManagedThreadId);
|
Watchdog.AbortThread(t.ManagedThreadId);
|
||||||
|
@ -135,7 +133,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||||
|
|
||||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||||
m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
|
|
||||||
|
|
||||||
if (m_workerThreads == null)
|
if (m_workerThreads == null)
|
||||||
{
|
{
|
||||||
|
@ -178,8 +175,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
|
|
||||||
public PollServiceInventoryEventArgs(Scene scene, UUID pId) :
|
public PollServiceInventoryEventArgs(Scene scene, string url, UUID pId) :
|
||||||
base(null, null, null, null, pId, int.MaxValue)
|
base(null, url, null, null, null, pId, int.MaxValue)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
|
||||||
|
@ -310,40 +307,39 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
if (m_fetchInventoryDescendents2Url == "")
|
if (m_fetchInventoryDescendents2Url == "")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string capUrl = "/CAPS/" + UUID.Random() + "/";
|
|
||||||
|
|
||||||
// Register this as a poll service
|
// Register this as a poll service
|
||||||
PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID);
|
PollServiceInventoryEventArgs args
|
||||||
|
= new PollServiceInventoryEventArgs(m_scene, "/CAPS/" + UUID.Random() + "/", agentID);
|
||||||
args.Type = PollServiceEventArgs.EventType.Inventory;
|
args.Type = PollServiceEventArgs.EventType.Inventory;
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
|
||||||
|
|
||||||
string hostName = m_scene.RegionInfo.ExternalHostName;
|
caps.RegisterPollHandler("FetchInventoryDescendents2", args);
|
||||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
|
||||||
string protocol = "http";
|
|
||||||
|
|
||||||
if (MainServer.Instance.UseSSL)
|
// MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
|
||||||
{
|
//
|
||||||
hostName = MainServer.Instance.SSLCommonName;
|
// string hostName = m_scene.RegionInfo.ExternalHostName;
|
||||||
port = MainServer.Instance.SSLPort;
|
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||||
protocol = "https";
|
// string protocol = "http";
|
||||||
}
|
//
|
||||||
|
// if (MainServer.Instance.UseSSL)
|
||||||
caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
// {
|
||||||
|
// hostName = MainServer.Instance.SSLCommonName;
|
||||||
m_capsDict[agentID] = capUrl;
|
// port = MainServer.Instance.SSLPort;
|
||||||
|
// protocol = "https";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeregisterCaps(UUID agentID, Caps caps)
|
// private void DeregisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
// {
|
||||||
string capUrl;
|
// string capUrl;
|
||||||
|
//
|
||||||
if (m_capsDict.TryGetValue(agentID, out capUrl))
|
// if (m_capsDict.TryGetValue(agentID, out capUrl))
|
||||||
{
|
// {
|
||||||
MainServer.Instance.RemoveHTTPHandler("", capUrl);
|
// MainServer.Instance.RemoveHTTPHandler("", capUrl);
|
||||||
m_capsDict.Remove(agentID);
|
// m_capsDict.Remove(agentID);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private void DoInventoryRequests()
|
private void DoInventoryRequests()
|
||||||
{
|
{
|
||||||
|
@ -353,7 +349,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
aPollRequest poolreq = m_queue.Dequeue();
|
aPollRequest poolreq = m_queue.Dequeue();
|
||||||
|
|
||||||
poolreq.thepoll.Process(poolreq);
|
if (poolreq != null && poolreq.thepoll != null)
|
||||||
|
poolreq.thepoll.Process(poolreq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3816,6 +3816,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ResendPrimUpdate(update);
|
ResendPrimUpdate(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
|
||||||
|
// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
//
|
||||||
|
// OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
// OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
// OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
// OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
|
||||||
|
|
||||||
private void ProcessEntityUpdates(int maxUpdates)
|
private void ProcessEntityUpdates(int maxUpdates)
|
||||||
{
|
{
|
||||||
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
@ -3828,6 +3839,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
|
||||||
|
|
||||||
|
// objectUpdateBlocks.Value.Clear();
|
||||||
|
// compressedUpdateBlocks.Value.Clear();
|
||||||
|
// terseUpdateBlocks.Value.Clear();
|
||||||
|
// terseAgentUpdateBlocks.Value.Clear();
|
||||||
|
// objectUpdates.Value.Clear();
|
||||||
|
// compressedUpdates.Value.Clear();
|
||||||
|
// terseUpdates.Value.Clear();
|
||||||
|
// terseAgentUpdates.Value.Clear();
|
||||||
|
|
||||||
// Check to see if this is a flush
|
// Check to see if this is a flush
|
||||||
if (maxUpdates <= 0)
|
if (maxUpdates <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -809,8 +809,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketPool.Instance.ReturnPacket(packet);
|
PacketPool.Instance.ReturnPacket(packet);
|
||||||
|
m_dataPresentEvent.Set();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start the process of sending a packet to the client.
|
/// Start the process of sending a packet to the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1730,6 +1734,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Action generic every round
|
// Action generic every round
|
||||||
Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
|
Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
|
||||||
|
|
||||||
|
// while (true)
|
||||||
while (base.IsRunningOutbound)
|
while (base.IsRunningOutbound)
|
||||||
{
|
{
|
||||||
m_scene.ThreadAlive(2);
|
m_scene.ThreadAlive(2);
|
||||||
|
@ -1791,8 +1796,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// If nothing was sent, sleep for the minimum amount of time before a
|
// If nothing was sent, sleep for the minimum amount of time before a
|
||||||
// token bucket could get more tokens
|
// token bucket could get more tokens
|
||||||
if (!m_packetSent)
|
//if (!m_packetSent)
|
||||||
Thread.Sleep((int)TickCountResolution);
|
// Thread.Sleep((int)TickCountResolution);
|
||||||
|
m_dataPresentEvent.WaitOne(100);
|
||||||
|
|
||||||
Watchdog.UpdateThread();
|
Watchdog.UpdateThread();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
|
|
||||||
|
|
||||||
if (Enabled)
|
if (Enabled)
|
||||||
{
|
{
|
||||||
|
// Only register module with scene if it is enabled. All callers check for a null attachments module.
|
||||||
|
// Ideally, there should be a null attachments module for when this core attachments module has been
|
||||||
|
// disabled. Registering only when enabled allows for other attachments module implementations.
|
||||||
|
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
|
||||||
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
||||||
m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true);
|
m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true);
|
||||||
m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false);
|
m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false);
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
|
|
||||||
MainConsole.Instance.Commands.AddCommand(
|
MainConsole.Instance.Commands.AddCommand(
|
||||||
"Comms", false, "show caps stats by user",
|
"Comms", false, "show caps stats by user",
|
||||||
"show caps stats [<first-name> <last-name>]",
|
"show caps stats by user [<first-name> <last-name>]",
|
||||||
"Shows statistics on capabilities use by user.",
|
"Shows statistics on capabilities use by user.",
|
||||||
"If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.",
|
"If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.",
|
||||||
HandleShowCapsStatsByUserCommand);
|
HandleShowCapsStatsByUserCommand);
|
||||||
|
@ -296,27 +296,31 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
StringBuilder caps = new StringBuilder();
|
StringBuilder capsReport = new StringBuilder();
|
||||||
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
capsReport.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
lock (m_capsObjects)
|
lock (m_capsObjects)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
|
foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
|
||||||
{
|
{
|
||||||
caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key);
|
||||||
|
Caps caps = kvp.Value;
|
||||||
|
|
||||||
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
|
for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
|
||||||
{
|
{
|
||||||
Uri uri = new Uri(kvp2.Value.ToString());
|
Uri uri = new Uri(kvp2.Value.ToString());
|
||||||
caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
foreach (KeyValuePair<string, PollServiceEventArgs> kvp2 in caps.GetPollHandlers())
|
||||||
caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
|
capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url);
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> kvp3 in caps.ExternalCapsHandlers)
|
||||||
|
capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output(caps.ToString());
|
MainConsole.Instance.Output(capsReport.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
|
private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
|
||||||
|
@ -375,6 +379,15 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
receivedStats[sp.Name] = reqHandler.RequestsReceived;
|
receivedStats[sp.Name] = reqHandler.RequestsReceived;
|
||||||
handledStats[sp.Name] = reqHandler.RequestsHandled;
|
handledStats[sp.Name] = reqHandler.RequestsHandled;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PollServiceEventArgs pollHandler = null;
|
||||||
|
if (caps.TryGetPollHandler(capName, out pollHandler))
|
||||||
|
{
|
||||||
|
receivedStats[sp.Name] = pollHandler.RequestsReceived;
|
||||||
|
handledStats[sp.Name] = pollHandler.RequestsHandled;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -407,9 +420,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
if (caps == null)
|
if (caps == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
|
foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
|
||||||
|
|
||||||
foreach (IRequestHandler reqHandler in capsHandlers.Values)
|
|
||||||
{
|
{
|
||||||
string reqName = reqHandler.Name ?? "";
|
string reqName = reqHandler.Name ?? "";
|
||||||
|
|
||||||
|
@ -424,6 +435,23 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
handledStats[reqName] += reqHandler.RequestsHandled;
|
handledStats[reqName] += reqHandler.RequestsHandled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
|
||||||
|
{
|
||||||
|
string name = kvp.Key;
|
||||||
|
PollServiceEventArgs pollHandler = kvp.Value;
|
||||||
|
|
||||||
|
if (!receivedStats.ContainsKey(name))
|
||||||
|
{
|
||||||
|
receivedStats[name] = pollHandler.RequestsReceived;
|
||||||
|
handledStats[name] = pollHandler.RequestsHandled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
receivedStats[name] += pollHandler.RequestsReceived;
|
||||||
|
handledStats[name] += pollHandler.RequestsHandled;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -486,12 +514,16 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
if (caps == null)
|
if (caps == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
|
List<CapTableRow> capRows = new List<CapTableRow>();
|
||||||
|
|
||||||
foreach (IRequestHandler reqHandler in capsHandlers.Values.OrderByDescending(rh => rh.RequestsReceived))
|
foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
|
||||||
{
|
capRows.Add(new CapTableRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled));
|
||||||
cdt.AddRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled);
|
|
||||||
}
|
foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
|
||||||
|
capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled));
|
||||||
|
|
||||||
|
foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived))
|
||||||
|
cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
|
||||||
|
|
||||||
sb.Append(cdt.ToString());
|
sb.Append(cdt.ToString());
|
||||||
*/
|
*/
|
||||||
|
@ -526,6 +558,14 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
totalRequestsHandled += reqHandler.RequestsHandled;
|
totalRequestsHandled += reqHandler.RequestsHandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary<string, PollServiceEventArgs> capsPollHandlers = caps.GetPollHandlers();
|
||||||
|
|
||||||
|
foreach (PollServiceEventArgs handler in capsPollHandlers.Values)
|
||||||
|
{
|
||||||
|
totalRequestsReceived += handler.RequestsReceived;
|
||||||
|
totalRequestsHandled += handler.RequestsHandled;
|
||||||
|
}
|
||||||
|
|
||||||
cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
|
cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -533,5 +573,19 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
sb.Append(cdt.ToString());
|
sb.Append(cdt.ToString());
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class CapTableRow
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int RequestsReceived { get; set; }
|
||||||
|
public int RequestsHandled { get; set; }
|
||||||
|
|
||||||
|
public CapTableRow(string name, int requestsReceived, int requestsHandled)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
RequestsReceived = requestsReceived;
|
||||||
|
RequestsHandled = requestsHandled;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,23 +42,37 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
namespace OpenSim.Region.CoreModules.Framework
|
namespace OpenSim.Region.CoreModules.Framework
|
||||||
{
|
{
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
|
||||||
public class GridServiceThrottleModule : ISharedRegionModule
|
public class ServiceThrottleModule : ISharedRegionModule, IServiceThrottleModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(
|
private static readonly ILog m_log = LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||||
|
private System.Timers.Timer m_timer = new System.Timers.Timer();
|
||||||
|
|
||||||
private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>();
|
private Queue<Action> m_RequestQueue = new Queue<Action>();
|
||||||
|
private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>();
|
||||||
|
private int m_Interval;
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
{
|
{
|
||||||
Watchdog.StartThread(
|
m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000);
|
||||||
ProcessQueue,
|
|
||||||
"GridServiceRequestThread",
|
m_timer = new System.Timers.Timer();
|
||||||
ThreadPriority.BelowNormal,
|
m_timer.AutoReset = false;
|
||||||
true,
|
m_timer.Enabled = true;
|
||||||
false);
|
m_timer.Interval = 15000; // 15 secs at first
|
||||||
|
m_timer.Elapsed += ProcessQueue;
|
||||||
|
m_timer.Start();
|
||||||
|
|
||||||
|
//Watchdog.StartThread(
|
||||||
|
// ProcessQueue,
|
||||||
|
// "GridServiceRequestThread",
|
||||||
|
// ThreadPriority.BelowNormal,
|
||||||
|
// true,
|
||||||
|
// false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
|
@ -66,7 +80,9 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
lock (m_scenes)
|
lock (m_scenes)
|
||||||
{
|
{
|
||||||
m_scenes.Add(scene);
|
m_scenes.Add(scene);
|
||||||
|
scene.RegisterModuleInterface<IServiceThrottleModule>(this);
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
|
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +99,6 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
client.OnRegionHandleRequest += OnRegionHandleRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -98,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return "GridServiceThrottleModule"; }
|
get { return "ServiceThrottleModule"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
|
@ -106,9 +117,31 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion ISharedRegionMOdule
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
void OnNewClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.OnRegionHandleRequest += OnRegionHandleRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnMakeRootAgent(ScenePresence obj)
|
||||||
|
{
|
||||||
|
lock (m_timer)
|
||||||
|
{
|
||||||
|
if (!m_timer.Enabled)
|
||||||
|
{
|
||||||
|
m_timer.Interval = m_Interval;
|
||||||
|
m_timer.Enabled = true;
|
||||||
|
m_timer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
|
public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
|
//m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
|
||||||
ulong handle = 0;
|
ulong handle = 0;
|
||||||
if (IsLocalRegionHandle(regionID, out handle))
|
if (IsLocalRegionHandle(regionID, out handle))
|
||||||
{
|
{
|
||||||
|
@ -116,11 +149,83 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GridRegionRequest request = new GridRegionRequest(client, regionID);
|
Action action = delegate
|
||||||
m_RequestQueue.Enqueue(request);
|
{
|
||||||
|
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
|
||||||
|
|
||||||
|
if (r != null && r.RegionHandle != 0)
|
||||||
|
client.SendRegionHandle(regionID, r.RegionHandle);
|
||||||
|
};
|
||||||
|
|
||||||
|
Enqueue("region", regionID.ToString(), action);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Events
|
||||||
|
|
||||||
|
#region IServiceThrottleModule
|
||||||
|
|
||||||
|
public void Enqueue(string category, string itemid, Action continuation)
|
||||||
|
{
|
||||||
|
lock (m_RequestQueue)
|
||||||
|
{
|
||||||
|
if (m_Pending.ContainsKey(category))
|
||||||
|
{
|
||||||
|
if (m_Pending[category].Contains(itemid))
|
||||||
|
// Don't enqueue, it's already pending
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_Pending.Add(category, new List<string>());
|
||||||
|
|
||||||
|
m_Pending[category].Add(itemid);
|
||||||
|
|
||||||
|
m_RequestQueue.Enqueue(delegate
|
||||||
|
{
|
||||||
|
lock (m_RequestQueue)
|
||||||
|
m_Pending[category].Remove(itemid);
|
||||||
|
|
||||||
|
continuation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion IServiceThrottleModule
|
||||||
|
|
||||||
|
#region Process Continuation Queue
|
||||||
|
|
||||||
|
private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count);
|
||||||
|
|
||||||
|
while (m_RequestQueue.Count > 0)
|
||||||
|
{
|
||||||
|
Action continuation = null;
|
||||||
|
lock (m_RequestQueue)
|
||||||
|
continuation = m_RequestQueue.Dequeue();
|
||||||
|
|
||||||
|
if (continuation != null)
|
||||||
|
continuation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AreThereRootAgents())
|
||||||
|
{
|
||||||
|
lock (m_timer)
|
||||||
|
{
|
||||||
|
m_timer.Interval = 1000; // 1 sec
|
||||||
|
m_timer.Enabled = true;
|
||||||
|
m_timer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lock (m_timer)
|
||||||
|
m_timer.Enabled = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Process Continuation Queue
|
||||||
|
|
||||||
|
#region Misc
|
||||||
|
|
||||||
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
|
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
|
||||||
{
|
{
|
||||||
regionHandle = 0;
|
regionHandle = 0;
|
||||||
|
@ -133,31 +238,19 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessQueue()
|
private bool AreThereRootAgents()
|
||||||
{
|
{
|
||||||
while (true)
|
foreach (Scene s in m_scenes)
|
||||||
{
|
{
|
||||||
Watchdog.UpdateThread();
|
foreach (ScenePresence sp in s.GetScenePresences())
|
||||||
|
if (!sp.IsChildAgent)
|
||||||
GridRegionRequest request = m_RequestQueue.Dequeue();
|
return true;
|
||||||
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID);
|
|
||||||
|
|
||||||
if (r != null && r.RegionHandle != 0)
|
|
||||||
request.client.SendRegionHandle(request.regionID, r.RegionHandle);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Misc
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridRegionRequest
|
|
||||||
{
|
|
||||||
public IClientAPI client;
|
|
||||||
public UUID regionID;
|
|
||||||
|
|
||||||
public GridRegionRequest(IClientAPI c, UUID r)
|
|
||||||
{
|
|
||||||
client = c;
|
|
||||||
regionID = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -56,13 +56,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
protected bool m_Enabled;
|
protected bool m_Enabled;
|
||||||
protected List<Scene> m_Scenes = new List<Scene>();
|
protected List<Scene> m_Scenes = new List<Scene>();
|
||||||
|
|
||||||
|
protected IServiceThrottleModule m_ServiceThrottle;
|
||||||
// The cache
|
// The cache
|
||||||
protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
|
protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
|
||||||
|
|
||||||
// Throttle the name requests
|
|
||||||
private OpenSim.Framework.BlockingQueue<NameRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<NameRequest>();
|
|
||||||
|
|
||||||
|
|
||||||
#region ISharedRegionModule
|
#region ISharedRegionModule
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
|
@ -115,6 +112,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public void RegionLoaded(Scene s)
|
public void RegionLoaded(Scene s)
|
||||||
{
|
{
|
||||||
|
if (m_Enabled && m_ServiceThrottle == null)
|
||||||
|
m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
@ -154,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
|
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
|
void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
|
// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
|
||||||
|
@ -162,12 +161,31 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
||||||
{
|
{
|
||||||
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
|
client.SendNameReply(uuid, "Mr", "OpenSim");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NameRequest request = new NameRequest(remote_client, uuid);
|
string[] names = new string[2];
|
||||||
m_RequestQueue.Enqueue(request);
|
if (TryGetUserNamesFromCache(uuid, names))
|
||||||
|
{
|
||||||
|
client.SendNameReply(uuid, names[0], names[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found in cache, queue continuation
|
||||||
|
m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[YYY]: Name request {0}", uuid);
|
||||||
|
bool foundRealName = TryGetUserNames(uuid, names);
|
||||||
|
|
||||||
|
if (names.Length == 2)
|
||||||
|
{
|
||||||
|
if (!foundRealName)
|
||||||
|
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, client.Name);
|
||||||
|
|
||||||
|
client.SendNameReply(uuid, names[0], names[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,15 +301,27 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Try to get the names bound to the given uuid.
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if the name was found, false if not.</returns>
|
/// <param name="uuid"></param>
|
||||||
/// <param name='uuid'></param>
|
/// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param>
|
||||||
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
/// <returns></returns>
|
||||||
private bool TryGetUserNames(UUID uuid, out string[] names)
|
private bool TryGetUserNames(UUID uuid, string[] names)
|
||||||
{
|
{
|
||||||
names = new string[2];
|
if (names == null)
|
||||||
|
names = new string[2];
|
||||||
|
|
||||||
|
if (TryGetUserNamesFromCache(uuid, names))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (TryGetUserNamesFromServices(uuid, names))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetUserNamesFromCache(UUID uuid, string[] names)
|
||||||
|
{
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
{
|
{
|
||||||
if (m_UserCache.ContainsKey(uuid))
|
if (m_UserCache.ContainsKey(uuid))
|
||||||
|
@ -303,6 +333,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to get the names bound to the given uuid, from the services.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the name was found, false if not.</returns>
|
||||||
|
/// <param name='uuid'></param>
|
||||||
|
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
||||||
|
private bool TryGetUserNamesFromServices(UUID uuid, string[] names)
|
||||||
|
{
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
|
||||||
|
|
||||||
if (account != null)
|
if (account != null)
|
||||||
|
@ -387,18 +428,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public string GetUserName(UUID uuid)
|
public string GetUserName(UUID uuid)
|
||||||
{
|
{
|
||||||
string[] names;
|
string[] names = new string[2];
|
||||||
TryGetUserNames(uuid, out names);
|
TryGetUserNames(uuid, names);
|
||||||
|
|
||||||
if (names.Length == 2)
|
return names[0] + " " + names[1];
|
||||||
{
|
|
||||||
string firstname = names[0];
|
|
||||||
string lastname = names[1];
|
|
||||||
|
|
||||||
return firstname + " " + lastname;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "(hippos)";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetUserHomeURL(UUID userID)
|
public string GetUserHomeURL(UUID userID)
|
||||||
|
@ -598,13 +632,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
protected void Init()
|
protected void Init()
|
||||||
{
|
{
|
||||||
RegisterConsoleCmds();
|
RegisterConsoleCmds();
|
||||||
Watchdog.StartThread(
|
|
||||||
ProcessQueue,
|
|
||||||
"NameRequestThread",
|
|
||||||
ThreadPriority.BelowNormal,
|
|
||||||
true,
|
|
||||||
false);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RegisterConsoleCmds()
|
protected void RegisterConsoleCmds()
|
||||||
|
@ -674,39 +701,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
MainConsole.Instance.Output(cdt.ToString());
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessQueue()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Watchdog.UpdateThread();
|
|
||||||
|
|
||||||
NameRequest request = m_RequestQueue.Dequeue();
|
|
||||||
string[] names;
|
|
||||||
bool foundRealName = TryGetUserNames(request.uuid, out names);
|
|
||||||
|
|
||||||
if (names.Length == 2)
|
|
||||||
{
|
|
||||||
if (!foundRealName)
|
|
||||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name);
|
|
||||||
|
|
||||||
request.client.SendNameReply(request.uuid, names[0], names[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class NameRequest
|
|
||||||
{
|
|
||||||
public IClientAPI client;
|
|
||||||
public UUID uuid;
|
|
||||||
|
|
||||||
public NameRequest(IClientAPI c, UUID n)
|
|
||||||
{
|
|
||||||
client = c;
|
|
||||||
uuid = n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -219,7 +219,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
string uri = "/lslhttp/" + urlcode.ToString();
|
string uri = "/lslhttp/" + urlcode.ToString();
|
||||||
|
|
||||||
PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
PollServiceEventArgs args
|
||||||
|
= new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
||||||
args.Type = PollServiceEventArgs.EventType.LslHttp;
|
args.Type = PollServiceEventArgs.EventType.LslHttp;
|
||||||
m_HttpServer.AddPollServiceHTTPHandler(uri, args);
|
m_HttpServer.AddPollServiceHTTPHandler(uri, args);
|
||||||
|
|
||||||
|
@ -266,7 +267,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
string uri = "/lslhttps/" + urlcode.ToString();
|
string uri = "/lslhttps/" + urlcode.ToString();
|
||||||
|
|
||||||
PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
PollServiceEventArgs args
|
||||||
|
= new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
|
||||||
args.Type = PollServiceEventArgs.EventType.LslHttp;
|
args.Type = PollServiceEventArgs.EventType.LslHttp;
|
||||||
m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
|
m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
{
|
||||||
|
public interface IServiceThrottleModule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enqueue a continuation meant to get a resource from elsewhere.
|
||||||
|
/// As usual with CPS, caller beware: if that continuation is a never-ending computation,
|
||||||
|
/// the whole thread will be blocked, and no requests are processed
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="category">Category of the resource (e.g. name, region)</param>
|
||||||
|
/// <param name="itemid">The resource identifier</param>
|
||||||
|
/// <param name="continuation">The continuation to be executed</param>
|
||||||
|
void Enqueue(string category, string itemid, Action continuation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -116,7 +116,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Delete existing npc attachments
|
// Delete existing npc attachments
|
||||||
scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
|
if(scene.AttachmentsModule != null)
|
||||||
|
scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
|
||||||
|
|
||||||
// XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet
|
// XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet
|
||||||
// since it doesn't transfer attachments
|
// since it doesn't transfer attachments
|
||||||
|
@ -125,7 +126,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
npc.Appearance = npcAppearance;
|
npc.Appearance = npcAppearance;
|
||||||
|
|
||||||
// Rez needed npc attachments
|
// Rez needed npc attachments
|
||||||
scene.AttachmentsModule.RezAttachments(npc);
|
if (scene.AttachmentsModule != null)
|
||||||
|
scene.AttachmentsModule.RezAttachments(npc);
|
||||||
|
|
||||||
IAvatarFactoryModule module =
|
IAvatarFactoryModule module =
|
||||||
scene.RequestModuleInterface<IAvatarFactoryModule>();
|
scene.RequestModuleInterface<IAvatarFactoryModule>();
|
||||||
|
|
|
@ -130,6 +130,7 @@ public class BSActorAvatarMove : BSActor
|
||||||
SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
|
SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
|
||||||
|
|
||||||
m_physicsScene.BeforeStep += Mover;
|
m_physicsScene.BeforeStep += Mover;
|
||||||
|
m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
|
||||||
|
|
||||||
m_walkingUpStairs = 0;
|
m_walkingUpStairs = 0;
|
||||||
}
|
}
|
||||||
|
@ -139,6 +140,7 @@ public class BSActorAvatarMove : BSActor
|
||||||
{
|
{
|
||||||
if (m_velocityMotor != null)
|
if (m_velocityMotor != null)
|
||||||
{
|
{
|
||||||
|
m_controllingPrim.OnPreUpdateProperty -= Process_OnPreUpdateProperty;
|
||||||
m_physicsScene.BeforeStep -= Mover;
|
m_physicsScene.BeforeStep -= Mover;
|
||||||
m_velocityMotor = null;
|
m_velocityMotor = null;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +199,7 @@ public class BSActorAvatarMove : BSActor
|
||||||
{
|
{
|
||||||
if (m_controllingPrim.Flying)
|
if (m_controllingPrim.Flying)
|
||||||
{
|
{
|
||||||
// Flying and not collising and velocity nearly zero.
|
// Flying and not colliding and velocity nearly zero.
|
||||||
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
|
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,6 +268,19 @@ public class BSActorAvatarMove : BSActor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called just as the property update is received from the physics engine.
|
||||||
|
// Do any mode necessary for avatar movement.
|
||||||
|
private void Process_OnPreUpdateProperty(ref EntityProperties entprop)
|
||||||
|
{
|
||||||
|
// Don't change position if standing on a stationary object.
|
||||||
|
if (m_controllingPrim.IsStationary)
|
||||||
|
{
|
||||||
|
entprop.Position = m_controllingPrim.RawPosition;
|
||||||
|
m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Decide if the character is colliding with a low object and compute a force to pop the
|
// Decide if the character is colliding with a low object and compute a force to pop the
|
||||||
// avatar up so it can walk up and over the low objects.
|
// avatar up so it can walk up and over the low objects.
|
||||||
private OMV.Vector3 WalkUpStairs()
|
private OMV.Vector3 WalkUpStairs()
|
||||||
|
|
|
@ -709,10 +709,10 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
// the world that things have changed.
|
// the world that things have changed.
|
||||||
public override void UpdateProperties(EntityProperties entprop)
|
public override void UpdateProperties(EntityProperties entprop)
|
||||||
{
|
{
|
||||||
// Don't change position if standing on a stationary object.
|
// Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
|
||||||
if (!IsStationary)
|
TriggerPreUpdatePropertyAction(ref entprop);
|
||||||
RawPosition = entprop.Position;
|
|
||||||
|
|
||||||
|
RawPosition = entprop.Position;
|
||||||
RawOrientation = entprop.Rotation;
|
RawOrientation = entprop.Rotation;
|
||||||
|
|
||||||
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
|
// Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
|
||||||
|
@ -740,7 +740,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
// Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
// Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
||||||
|
|
||||||
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
|
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
|
||||||
// base.RequestPhysicsterseUpdate();
|
// PhysScene.PostUpdate(this);
|
||||||
|
|
||||||
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||||
LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity);
|
LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity);
|
||||||
|
|
|
@ -103,9 +103,10 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
CollisionsLastTickStep = -1;
|
CollisionsLastTickStep = -1;
|
||||||
|
|
||||||
SubscribedEventsMs = 0;
|
SubscribedEventsMs = 0;
|
||||||
CollidingStep = 0;
|
// Crazy values that will never be true
|
||||||
CollidingGroundStep = 0;
|
CollidingStep = BSScene.NotASimulationStep;
|
||||||
CollisionAccumulation = 0;
|
CollidingGroundStep = BSScene.NotASimulationStep;
|
||||||
|
CollisionAccumulation = BSScene.NotASimulationStep;
|
||||||
ColliderIsMoving = false;
|
ColliderIsMoving = false;
|
||||||
CollisionScore = 0;
|
CollisionScore = 0;
|
||||||
|
|
||||||
|
@ -349,7 +350,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
if (value)
|
if (value)
|
||||||
CollidingStep = PhysScene.SimulationStep;
|
CollidingStep = PhysScene.SimulationStep;
|
||||||
else
|
else
|
||||||
CollidingStep = 0;
|
CollidingStep = BSScene.NotASimulationStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override bool CollidingGround {
|
public override bool CollidingGround {
|
||||||
|
@ -359,7 +360,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
if (value)
|
if (value)
|
||||||
CollidingGroundStep = PhysScene.SimulationStep;
|
CollidingGroundStep = PhysScene.SimulationStep;
|
||||||
else
|
else
|
||||||
CollidingGroundStep = 0;
|
CollidingGroundStep = BSScene.NotASimulationStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override bool CollidingObj {
|
public override bool CollidingObj {
|
||||||
|
@ -368,7 +369,7 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
if (value)
|
if (value)
|
||||||
CollidingObjectStep = PhysScene.SimulationStep;
|
CollidingObjectStep = PhysScene.SimulationStep;
|
||||||
else
|
else
|
||||||
CollidingObjectStep = 0;
|
CollidingObjectStep = BSScene.NotASimulationStep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
internal long m_simulationStep = 0; // The current simulation step.
|
internal long m_simulationStep = 0; // The current simulation step.
|
||||||
public long SimulationStep { get { return m_simulationStep; } }
|
public long SimulationStep { get { return m_simulationStep; } }
|
||||||
|
// A number to use for SimulationStep that is probably not any step value
|
||||||
|
// Used by the collision code (which remembers the step when a collision happens) to remember not any simulation step.
|
||||||
|
public static long NotASimulationStep = -1234;
|
||||||
|
|
||||||
internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate()
|
internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate()
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,8 @@ namespace OpenSim.Region.RegionCombinerModule
|
||||||
m_virtScene.UnSubscribeToClientPrimEvents(client);
|
m_virtScene.UnSubscribeToClientPrimEvents(client);
|
||||||
m_virtScene.UnSubscribeToClientPrimRezEvents(client);
|
m_virtScene.UnSubscribeToClientPrimRezEvents(client);
|
||||||
m_virtScene.UnSubscribeToClientInventoryEvents(client);
|
m_virtScene.UnSubscribeToClientInventoryEvents(client);
|
||||||
((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client);
|
if(m_virtScene.AttachmentsModule != null)
|
||||||
|
((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client);
|
||||||
//m_virtScene.UnSubscribeToClientTeleportEvents(client);
|
//m_virtScene.UnSubscribeToClientTeleportEvents(client);
|
||||||
m_virtScene.UnSubscribeToClientScriptEvents(client);
|
m_virtScene.UnSubscribeToClientScriptEvents(client);
|
||||||
|
|
||||||
|
@ -66,7 +67,8 @@ namespace OpenSim.Region.RegionCombinerModule
|
||||||
client.OnRezObject += LocalRezObject;
|
client.OnRezObject += LocalRezObject;
|
||||||
|
|
||||||
m_rootScene.SubscribeToClientInventoryEvents(client);
|
m_rootScene.SubscribeToClientInventoryEvents(client);
|
||||||
((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client);
|
if (m_rootScene.AttachmentsModule != null)
|
||||||
|
((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client);
|
||||||
//m_rootScene.SubscribeToClientTeleportEvents(client);
|
//m_rootScene.SubscribeToClientTeleportEvents(client);
|
||||||
m_rootScene.SubscribeToClientScriptEvents(client);
|
m_rootScene.SubscribeToClientScriptEvents(client);
|
||||||
|
|
||||||
|
|
|
@ -1723,5 +1723,9 @@ MaxStringSpace = 0
|
||||||
;; {MaxDistance} {} {Cut-off distance at which sounds will not be sent to users} {100.0}
|
;; {MaxDistance} {} {Cut-off distance at which sounds will not be sent to users} {100.0}
|
||||||
MaxDistance = 100.0
|
MaxDistance = 100.0
|
||||||
|
|
||||||
|
[ServiceThrottle]
|
||||||
|
;; Default time interval (in ms) for the throttle service thread to wake up
|
||||||
|
Interval = 5000
|
||||||
|
|
||||||
[Modules]
|
[Modules]
|
||||||
Include-modules = "addon-modules/*/config/*.ini"
|
Include-modules = "addon-modules/*/config/*.ini"
|
||||||
|
|
Loading…
Reference in New Issue