diff options
31 files changed, 657 insertions, 278 deletions
diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index 95fc61b..30a323e 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs | |||
@@ -64,7 +64,11 @@ namespace OpenSim.Framework.Capabilities | |||
64 | public string CapsObjectPath { get { return m_capsObjectPath; } } | 64 | public string CapsObjectPath { get { return m_capsObjectPath; } } |
65 | 65 | ||
66 | private CapsHandlers m_capsHandlers; | 66 | private CapsHandlers m_capsHandlers; |
67 | private Dictionary<string, string> m_externalCapsHandlers; | 67 | |
68 | private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers | ||
69 | = new Dictionary<string, PollServiceEventArgs>(); | ||
70 | |||
71 | private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>(); | ||
68 | 72 | ||
69 | private IHttpServer m_httpListener; | 73 | private IHttpServer m_httpListener; |
70 | private UUID m_agentID; | 74 | private UUID m_agentID; |
@@ -134,7 +138,6 @@ namespace OpenSim.Framework.Capabilities | |||
134 | 138 | ||
135 | m_agentID = agent; | 139 | m_agentID = agent; |
136 | m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); | 140 | m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); |
137 | m_externalCapsHandlers = new Dictionary<string, string>(); | ||
138 | m_regionName = regionName; | 141 | m_regionName = regionName; |
139 | } | 142 | } |
140 | 143 | ||
@@ -149,6 +152,27 @@ namespace OpenSim.Framework.Capabilities | |||
149 | m_capsHandlers[capName] = handler; | 152 | m_capsHandlers[capName] = handler; |
150 | } | 153 | } |
151 | 154 | ||
155 | public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler) | ||
156 | { | ||
157 | m_pollServiceHandlers.Add(capName, pollServiceHandler); | ||
158 | |||
159 | m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler); | ||
160 | |||
161 | // uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; | ||
162 | // string protocol = "http"; | ||
163 | // string hostName = m_httpListenerHostName; | ||
164 | // | ||
165 | // if (MainServer.Instance.UseSSL) | ||
166 | // { | ||
167 | // hostName = MainServer.Instance.SSLCommonName; | ||
168 | // port = MainServer.Instance.SSLPort; | ||
169 | // protocol = "https"; | ||
170 | // } | ||
171 | |||
172 | // RegisterHandler( | ||
173 | // capName, String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, pollServiceHandler.Url)); | ||
174 | } | ||
175 | |||
152 | /// <summary> | 176 | /// <summary> |
153 | /// Register an external handler. The service for this capability is somewhere else | 177 | /// Register an external handler. The service for this capability is somewhere else |
154 | /// given by the URL. | 178 | /// given by the URL. |
@@ -165,13 +189,70 @@ namespace OpenSim.Framework.Capabilities | |||
165 | /// </summary> | 189 | /// </summary> |
166 | public void DeregisterHandlers() | 190 | public void DeregisterHandlers() |
167 | { | 191 | { |
168 | if (m_capsHandlers != null) | 192 | foreach (string capsName in m_capsHandlers.Caps) |
193 | { | ||
194 | m_capsHandlers.Remove(capsName); | ||
195 | } | ||
196 | |||
197 | foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values) | ||
198 | { | ||
199 | m_httpListener.RemovePollServiceHTTPHandler("", handler.Url); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler) | ||
204 | { | ||
205 | return m_pollServiceHandlers.TryGetValue(name, out pollHandler); | ||
206 | } | ||
207 | |||
208 | public Dictionary<string, PollServiceEventArgs> GetPollHandlers() | ||
209 | { | ||
210 | return new Dictionary<string, PollServiceEventArgs>(m_pollServiceHandlers); | ||
211 | } | ||
212 | |||
213 | /// <summary> | ||
214 | /// Return an LLSD-serializable Hashtable describing the | ||
215 | /// capabilities and their handler details. | ||
216 | /// </summary> | ||
217 | /// <param name="excludeSeed">If true, then exclude the seed cap.</param> | ||
218 | public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps) | ||
219 | { | ||
220 | Hashtable caps = CapsHandlers.GetCapsDetails(excludeSeed, requestedCaps); | ||
221 | |||
222 | lock (m_pollServiceHandlers) | ||
169 | { | 223 | { |
170 | foreach (string capsName in m_capsHandlers.Caps) | 224 | foreach (KeyValuePair <string, PollServiceEventArgs> kvp in m_pollServiceHandlers) |
171 | { | 225 | { |
172 | m_capsHandlers.Remove(capsName); | 226 | if (!requestedCaps.Contains(kvp.Key)) |
227 | continue; | ||
228 | |||
229 | string hostName = m_httpListenerHostName; | ||
230 | uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; | ||
231 | string protocol = "http"; | ||
232 | |||
233 | if (MainServer.Instance.UseSSL) | ||
234 | { | ||
235 | hostName = MainServer.Instance.SSLCommonName; | ||
236 | port = MainServer.Instance.SSLPort; | ||
237 | protocol = "https"; | ||
238 | } | ||
239 | // | ||
240 | // caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); | ||
241 | |||
242 | caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url); | ||
173 | } | 243 | } |
174 | } | 244 | } |
245 | |||
246 | // Add the external too | ||
247 | foreach (KeyValuePair<string, string> kvp in ExternalCapsHandlers) | ||
248 | { | ||
249 | if (!requestedCaps.Contains(kvp.Key)) | ||
250 | continue; | ||
251 | |||
252 | caps[kvp.Key] = kvp.Value; | ||
253 | } | ||
254 | |||
255 | return caps; | ||
175 | } | 256 | } |
176 | 257 | ||
177 | public void Activate() | 258 | public void Activate() |
@@ -185,4 +266,4 @@ namespace OpenSim.Framework.Capabilities | |||
185 | return m_capsActive.WaitOne(30000); | 266 | return m_capsActive.WaitOne(30000); |
186 | } | 267 | } |
187 | } | 268 | } |
188 | } | 269 | } \ No newline at end of file |
diff --git a/OpenSim/Data/Null/NullSimulationData.cs b/OpenSim/Data/Null/NullSimulationData.cs index e7e5c41..15824a9 100644 --- a/OpenSim/Data/Null/NullSimulationData.cs +++ b/OpenSim/Data/Null/NullSimulationData.cs | |||
@@ -77,20 +77,34 @@ namespace OpenSim.Data.Null | |||
77 | } | 77 | } |
78 | 78 | ||
79 | #region Environment Settings | 79 | #region Environment Settings |
80 | |||
81 | private Dictionary<UUID, string> EnvironmentSettings = new Dictionary<UUID, string>(); | ||
82 | |||
80 | public string LoadRegionEnvironmentSettings(UUID regionUUID) | 83 | public string LoadRegionEnvironmentSettings(UUID regionUUID) |
81 | { | 84 | { |
82 | //This connector doesn't support the Environment module yet | 85 | lock (EnvironmentSettings) |
86 | { | ||
87 | if (EnvironmentSettings.ContainsKey(regionUUID)) | ||
88 | return EnvironmentSettings[regionUUID]; | ||
89 | } | ||
83 | return string.Empty; | 90 | return string.Empty; |
84 | } | 91 | } |
85 | 92 | ||
86 | public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) | 93 | public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) |
87 | { | 94 | { |
88 | //This connector doesn't support the Environment module yet | 95 | lock (EnvironmentSettings) |
96 | { | ||
97 | EnvironmentSettings[regionUUID] = settings; | ||
98 | } | ||
89 | } | 99 | } |
90 | 100 | ||
91 | public void RemoveRegionEnvironmentSettings(UUID regionUUID) | 101 | public void RemoveRegionEnvironmentSettings(UUID regionUUID) |
92 | { | 102 | { |
93 | //This connector doesn't support the Environment module yet | 103 | lock (EnvironmentSettings) |
104 | { | ||
105 | if (EnvironmentSettings.ContainsKey(regionUUID)) | ||
106 | EnvironmentSettings.Remove(regionUUID); | ||
107 | } | ||
94 | } | 108 | } |
95 | #endregion | 109 | #endregion |
96 | 110 | ||
diff --git a/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations index 2e73caa..02612ce 100644 --- a/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations +++ b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations | |||
@@ -1,18 +1,18 @@ | |||
1 | :VERSION 1 # -------------------------- | 1 | :VERSION 2 # -------------------------- |
2 | 2 | ||
3 | BEGIN; | 3 | BEGIN; |
4 | 4 | ||
5 | CREATE TABLE hg_traveling_data ( | 5 | CREATE TABLE hg_traveling_data( |
6 | SessionID VARCHAR(36) NOT NULL, | 6 | SessionID VARCHAR(36) NOT NULL, |
7 | UserID VARCHAR(36) NOT NULL, | 7 | UserID VARCHAR(36) NOT NULL, |
8 | GridExternalName VARCHAR(255) NOT NULL DEFAULT '', | 8 | GridExternalName VARCHAR(255) NOT NULL DEFAULT "", |
9 | ServiceToken VARCHAR(255) NOT NULL DEFAULT '', | 9 | ServiceToken VARCHAR(255) NOT NULL DEFAULT "", |
10 | ClientIPAddress VARCHAR(16) NOT NULL DEFAULT '', | 10 | ClientIPAddress VARCHAR(16) NOT NULL DEFAULT "", |
11 | MyIPAddress VARCHAR(16) NOT NULL DEFAULT '', | 11 | MyIPAddress VARCHAR(16) NOT NULL DEFAULT "", |
12 | TMStamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | 12 | TMStamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
13 | PRIMARY KEY (`SessionID`), | 13 | PRIMARY KEY(SessionID), |
14 | KEY (`UserID`) | 14 | UNIQUE(UserID) |
15 | ) ENGINE=InnoDB; | 15 | ); |
16 | 16 | ||
17 | COMMIT; | 17 | COMMIT; |
18 | 18 | ||
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index 3658161..3e90fac 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs | |||
@@ -58,7 +58,7 @@ namespace OpenSim.Framework | |||
58 | { | 58 | { |
59 | lock (m_queueSync) | 59 | lock (m_queueSync) |
60 | { | 60 | { |
61 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | 61 | while (m_queue.Count < 1 && m_pqueue.Count < 1) |
62 | { | 62 | { |
63 | Monitor.Wait(m_queueSync); | 63 | Monitor.Wait(m_queueSync); |
64 | } | 64 | } |
@@ -76,9 +76,10 @@ namespace OpenSim.Framework | |||
76 | { | 76 | { |
77 | lock (m_queueSync) | 77 | lock (m_queueSync) |
78 | { | 78 | { |
79 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | 79 | bool success = true; |
80 | while (m_queue.Count < 1 && m_pqueue.Count < 1 && success) | ||
80 | { | 81 | { |
81 | Monitor.Wait(m_queueSync, msTimeout); | 82 | success = Monitor.Wait(m_queueSync, msTimeout); |
82 | } | 83 | } |
83 | 84 | ||
84 | if (m_pqueue.Count > 0) | 85 | if (m_pqueue.Count > 0) |
@@ -89,8 +90,17 @@ namespace OpenSim.Framework | |||
89 | } | 90 | } |
90 | } | 91 | } |
91 | 92 | ||
93 | /// <summary> | ||
94 | /// Indicate whether this queue contains the given item. | ||
95 | /// </summary> | ||
96 | /// <remarks> | ||
97 | /// This method is not thread-safe. Do not rely on the result without consistent external locking. | ||
98 | /// </remarks> | ||
92 | public bool Contains(T item) | 99 | public bool Contains(T item) |
93 | { | 100 | { |
101 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
102 | return false; | ||
103 | |||
94 | lock (m_queueSync) | 104 | lock (m_queueSync) |
95 | { | 105 | { |
96 | if (m_pqueue.Contains(item)) | 106 | if (m_pqueue.Contains(item)) |
@@ -99,16 +109,28 @@ namespace OpenSim.Framework | |||
99 | } | 109 | } |
100 | } | 110 | } |
101 | 111 | ||
112 | /// <summary> | ||
113 | /// Return a count of the number of requests on this queue. | ||
114 | /// </summary> | ||
115 | /// <remarks> | ||
116 | /// This method is not thread-safe. Do not rely on the result without consistent external locking. | ||
117 | /// </remarks> | ||
102 | public int Count() | 118 | public int Count() |
103 | { | 119 | { |
104 | lock (m_queueSync) | 120 | return m_queue.Count + m_pqueue.Count; |
105 | { | ||
106 | return m_queue.Count+m_pqueue.Count; | ||
107 | } | ||
108 | } | 121 | } |
109 | 122 | ||
123 | /// <summary> | ||
124 | /// Return the array of items on this queue. | ||
125 | /// </summary> | ||
126 | /// <remarks> | ||
127 | /// This method is not thread-safe. Do not rely on the result without consistent external locking. | ||
128 | /// </remarks> | ||
110 | public T[] GetQueueArray() | 129 | public T[] GetQueueArray() |
111 | { | 130 | { |
131 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
132 | return new T[0]; | ||
133 | |||
112 | lock (m_queueSync) | 134 | lock (m_queueSync) |
113 | { | 135 | { |
114 | return m_queue.ToArray(); | 136 | return m_queue.ToArray(); |
diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 3e3c2b3..8ad7b0d 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs | |||
@@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console | |||
234 | string uri = "/ReadResponses/" + sessionID.ToString() + "/"; | 234 | string uri = "/ReadResponses/" + sessionID.ToString() + "/"; |
235 | 235 | ||
236 | m_Server.AddPollServiceHTTPHandler( | 236 | m_Server.AddPollServiceHTTPHandler( |
237 | uri, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout | 237 | uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout |
238 | 238 | ||
239 | XmlDocument xmldoc = new XmlDocument(); | 239 | XmlDocument xmldoc = new XmlDocument(); |
240 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, | 240 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, |
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 0fde42c..f4b4156 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -387,6 +387,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
387 | 387 | ||
388 | if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs)) | 388 | if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs)) |
389 | { | 389 | { |
390 | psEvArgs.RequestsReceived++; | ||
391 | |||
390 | PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request); | 392 | PollServiceHttpRequest psreq = new PollServiceHttpRequest(psEvArgs, context, request); |
391 | 393 | ||
392 | if (psEvArgs.Request != null) | 394 | if (psEvArgs.Request != null) |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index c19ac32..3fd3bf7 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs | |||
@@ -50,25 +50,39 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
50 | 50 | ||
51 | public enum EventType : int | 51 | public enum EventType : int |
52 | { | 52 | { |
53 | Normal = 0, | 53 | LongPoll = 0, |
54 | LslHttp = 1, | 54 | LslHttp = 1, |
55 | Inventory = 2, | 55 | Inventory = 2, |
56 | Texture = 3, | 56 | Texture = 3, |
57 | Mesh = 4 | 57 | Mesh = 4 |
58 | } | 58 | } |
59 | 59 | ||
60 | public string Url { get; set; } | ||
61 | |||
62 | /// <summary> | ||
63 | /// Number of requests received for this poll service. | ||
64 | /// </summary> | ||
65 | public int RequestsReceived { get; set; } | ||
66 | |||
67 | /// <summary> | ||
68 | /// Number of requests handled by this poll service. | ||
69 | /// </summary> | ||
70 | public int RequestsHandled { get; set; } | ||
71 | |||
60 | public PollServiceEventArgs( | 72 | public PollServiceEventArgs( |
61 | RequestMethod pRequest, | 73 | RequestMethod pRequest, |
74 | string pUrl, | ||
62 | HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, | 75 | HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, |
63 | UUID pId, int pTimeOutms) | 76 | UUID pId, int pTimeOutms) |
64 | { | 77 | { |
65 | Request = pRequest; | 78 | Request = pRequest; |
79 | Url = pUrl; | ||
66 | HasEvents = pHasEvents; | 80 | HasEvents = pHasEvents; |
67 | GetEvents = pGetEvents; | 81 | GetEvents = pGetEvents; |
68 | NoEvents = pNoEvents; | 82 | NoEvents = pNoEvents; |
69 | Id = pId; | 83 | Id = pId; |
70 | TimeOutms = pTimeOutms; | 84 | TimeOutms = pTimeOutms; |
71 | Type = EventType.Normal; | 85 | Type = EventType.LongPoll; |
72 | } | 86 | } |
73 | } | 87 | } |
74 | } | 88 | } |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index 723530a..6aa9479 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs | |||
@@ -26,13 +26,19 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
29 | using HttpServer; | 32 | using HttpServer; |
33 | using log4net; | ||
30 | using OpenMetaverse; | 34 | using OpenMetaverse; |
31 | 35 | ||
32 | namespace OpenSim.Framework.Servers.HttpServer | 36 | namespace OpenSim.Framework.Servers.HttpServer |
33 | { | 37 | { |
34 | public class PollServiceHttpRequest | 38 | public class PollServiceHttpRequest |
35 | { | 39 | { |
40 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
41 | |||
36 | public readonly PollServiceEventArgs PollServiceArgs; | 42 | public readonly PollServiceEventArgs PollServiceArgs; |
37 | public readonly IHttpClientContext HttpContext; | 43 | public readonly IHttpClientContext HttpContext; |
38 | public readonly IHttpRequest Request; | 44 | public readonly IHttpRequest Request; |
@@ -48,5 +54,44 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
48 | RequestTime = System.Environment.TickCount; | 54 | RequestTime = System.Environment.TickCount; |
49 | RequestID = UUID.Random(); | 55 | RequestID = UUID.Random(); |
50 | } | 56 | } |
57 | |||
58 | internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) | ||
59 | { | ||
60 | OSHttpResponse response | ||
61 | = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); | ||
62 | |||
63 | byte[] buffer = server.DoHTTPGruntWork(responsedata, response); | ||
64 | |||
65 | response.SendChunked = false; | ||
66 | response.ContentLength64 = buffer.Length; | ||
67 | response.ContentEncoding = Encoding.UTF8; | ||
68 | |||
69 | try | ||
70 | { | ||
71 | response.OutputStream.Write(buffer, 0, buffer.Length); | ||
72 | } | ||
73 | catch (Exception ex) | ||
74 | { | ||
75 | m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex)); | ||
76 | } | ||
77 | finally | ||
78 | { | ||
79 | //response.OutputStream.Close(); | ||
80 | try | ||
81 | { | ||
82 | response.OutputStream.Flush(); | ||
83 | response.Send(); | ||
84 | |||
85 | //if (!response.KeepAlive && response.ReuseContext) | ||
86 | // response.FreeContext(); | ||
87 | } | ||
88 | catch (Exception e) | ||
89 | { | ||
90 | m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e)); | ||
91 | } | ||
92 | |||
93 | PollServiceArgs.RequestsHandled++; | ||
94 | } | ||
95 | } | ||
51 | } | 96 | } |
52 | } \ No newline at end of file | 97 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 98789be..44f7045 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -105,7 +105,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
105 | { | 105 | { |
106 | if (m_running) | 106 | if (m_running) |
107 | { | 107 | { |
108 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal) | 108 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll) |
109 | { | 109 | { |
110 | m_requests.Enqueue(req); | 110 | m_requests.Enqueue(req); |
111 | } | 111 | } |
@@ -207,7 +207,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
207 | if (responsedata == null) | 207 | if (responsedata == null) |
208 | continue; | 208 | continue; |
209 | 209 | ||
210 | if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) // This is the event queue | 210 | if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue |
211 | { | 211 | { |
212 | try | 212 | try |
213 | { | 213 | { |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 6c7af12..19d40db 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -1791,10 +1791,12 @@ namespace OpenSim.Framework | |||
1791 | FireAndForget(callback, null); | 1791 | FireAndForget(callback, null); |
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | public static void InitThreadPool(int maxThreads) | 1794 | public static void InitThreadPool(int minThreads, int maxThreads) |
1795 | { | 1795 | { |
1796 | if (maxThreads < 2) | 1796 | if (maxThreads < 2) |
1797 | throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2"); | 1797 | throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2"); |
1798 | if (minThreads > maxThreads || minThreads < 2) | ||
1799 | throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads"); | ||
1798 | if (m_ThreadPool != null) | 1800 | if (m_ThreadPool != null) |
1799 | throw new InvalidOperationException("SmartThreadPool is already initialized"); | 1801 | throw new InvalidOperationException("SmartThreadPool is already initialized"); |
1800 | 1802 | ||
@@ -1802,7 +1804,7 @@ namespace OpenSim.Framework | |||
1802 | startInfo.ThreadPoolName = "Util"; | 1804 | startInfo.ThreadPoolName = "Util"; |
1803 | startInfo.IdleTimeout = 2000; | 1805 | startInfo.IdleTimeout = 2000; |
1804 | startInfo.MaxWorkerThreads = maxThreads; | 1806 | startInfo.MaxWorkerThreads = maxThreads; |
1805 | startInfo.MinWorkerThreads = 2; | 1807 | startInfo.MinWorkerThreads = minThreads; |
1806 | 1808 | ||
1807 | m_ThreadPool = new SmartThreadPool(startInfo); | 1809 | m_ThreadPool = new SmartThreadPool(startInfo); |
1808 | } | 1810 | } |
@@ -1877,7 +1879,7 @@ namespace OpenSim.Framework | |||
1877 | break; | 1879 | break; |
1878 | case FireAndForgetMethod.SmartThreadPool: | 1880 | case FireAndForgetMethod.SmartThreadPool: |
1879 | if (m_ThreadPool == null) | 1881 | if (m_ThreadPool == null) |
1880 | InitThreadPool(15); | 1882 | InitThreadPool(2, 15); |
1881 | m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj); | 1883 | m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj); |
1882 | break; | 1884 | break; |
1883 | case FireAndForgetMethod.Thread: | 1885 | case FireAndForgetMethod.Thread: |
@@ -2265,7 +2267,7 @@ namespace OpenSim.Framework | |||
2265 | { | 2267 | { |
2266 | lock (m_syncRoot) | 2268 | lock (m_syncRoot) |
2267 | { | 2269 | { |
2268 | m_lowQueue.Enqueue(data); | 2270 | q.Enqueue(data); |
2269 | m_s.WaitOne(0); | 2271 | m_s.WaitOne(0); |
2270 | m_s.Release(); | 2272 | m_s.Release(); |
2271 | } | 2273 | } |
@@ -2305,7 +2307,7 @@ namespace OpenSim.Framework | |||
2305 | { | 2307 | { |
2306 | if (m_highQueue.Count > 0) | 2308 | if (m_highQueue.Count > 0) |
2307 | res = m_highQueue.Dequeue(); | 2309 | res = m_highQueue.Dequeue(); |
2308 | else | 2310 | else if (m_lowQueue.Count > 0) |
2309 | res = m_lowQueue.Dequeue(); | 2311 | res = m_lowQueue.Dequeue(); |
2310 | 2312 | ||
2311 | if (m_highQueue.Count == 0 && m_lowQueue.Count == 0) | 2313 | if (m_highQueue.Count == 0 && m_lowQueue.Count == 0) |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 87c2792..6dd1f5b 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -86,6 +86,7 @@ namespace OpenSim | |||
86 | IConfig startupConfig = Config.Configs["Startup"]; | 86 | IConfig startupConfig = Config.Configs["Startup"]; |
87 | IConfig networkConfig = Config.Configs["Network"]; | 87 | IConfig networkConfig = Config.Configs["Network"]; |
88 | 88 | ||
89 | int stpMinThreads = 2; | ||
89 | int stpMaxThreads = 15; | 90 | int stpMaxThreads = 15; |
90 | 91 | ||
91 | if (startupConfig != null) | 92 | if (startupConfig != null) |
@@ -112,12 +113,13 @@ namespace OpenSim | |||
112 | if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) | 113 | if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) |
113 | Util.FireAndForgetMethod = asyncCallMethod; | 114 | Util.FireAndForgetMethod = asyncCallMethod; |
114 | 115 | ||
116 | stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15); | ||
115 | stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15); | 117 | stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15); |
116 | m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) "); | 118 | m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) "); |
117 | } | 119 | } |
118 | 120 | ||
119 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) | 121 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) |
120 | Util.InitThreadPool(stpMaxThreads); | 122 | Util.InitThreadPool(stpMinThreads, stpMaxThreads); |
121 | 123 | ||
122 | m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); | 124 | m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); |
123 | } | 125 | } |
@@ -423,8 +425,8 @@ namespace OpenSim | |||
423 | { | 425 | { |
424 | RegionInfo regionInfo = presence.Scene.RegionInfo; | 426 | RegionInfo regionInfo = presence.Scene.RegionInfo; |
425 | 427 | ||
426 | if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) && | 428 | if (presence.Firstname.ToLower().Equals(mainParams[2].ToLower()) && |
427 | presence.Lastname.ToLower().Contains(mainParams[3].ToLower())) | 429 | presence.Lastname.ToLower().Equals(mainParams[3].ToLower())) |
428 | { | 430 | { |
429 | MainConsole.Instance.Output( | 431 | MainConsole.Instance.Output( |
430 | String.Format( | 432 | String.Format( |
@@ -438,6 +440,7 @@ namespace OpenSim | |||
438 | presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n"); | 440 | presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n"); |
439 | 441 | ||
440 | presence.Scene.IncomingCloseAgent(presence.UUID, force); | 442 | presence.Scene.IncomingCloseAgent(presence.UUID, force); |
443 | break; | ||
441 | } | 444 | } |
442 | } | 445 | } |
443 | 446 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 98ab433..762e22a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | |||
@@ -367,18 +367,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
367 | foreach (OSD c in capsRequested) | 367 | foreach (OSD c in capsRequested) |
368 | validCaps.Add(c.AsString()); | 368 | validCaps.Add(c.AsString()); |
369 | 369 | ||
370 | Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true, validCaps); | 370 | string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.GetCapsDetails(true, validCaps)); |
371 | |||
372 | // Add the external too | ||
373 | foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers) | ||
374 | { | ||
375 | if (!validCaps.Contains(kvp.Key)) | ||
376 | continue; | ||
377 | |||
378 | caps[kvp.Key] = kvp.Value; | ||
379 | } | ||
380 | |||
381 | string result = LLSDHelpers.SerialiseLLSDReply(caps); | ||
382 | 371 | ||
383 | //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); | 372 | //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); |
384 | 373 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index d6689d4..e98a470 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | |||
@@ -65,6 +65,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
65 | /// </value> | 65 | /// </value> |
66 | public int DebugLevel { get; set; } | 66 | public int DebugLevel { get; set; } |
67 | 67 | ||
68 | // Viewer post requests timeout in 60 secs | ||
69 | // https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44 | ||
70 | // | ||
71 | private const int VIEWER_TIMEOUT = 60 * 1000; | ||
72 | // Just to be safe, we work on a 10 sec shorter cycle | ||
73 | private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000); | ||
74 | |||
68 | protected Scene m_scene; | 75 | protected Scene m_scene; |
69 | 76 | ||
70 | private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); | 77 | private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); |
@@ -252,29 +259,32 @@ namespace OpenSim.Region.ClientStack.Linden | |||
252 | 259 | ||
253 | List<UUID> removeitems = new List<UUID>(); | 260 | List<UUID> removeitems = new List<UUID>(); |
254 | lock (m_AvatarQueueUUIDMapping) | 261 | lock (m_AvatarQueueUUIDMapping) |
255 | { | 262 | m_AvatarQueueUUIDMapping.Remove(agentID); |
256 | foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) | ||
257 | { | ||
258 | // m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); | ||
259 | if (ky == agentID) | ||
260 | { | ||
261 | removeitems.Add(ky); | ||
262 | } | ||
263 | } | ||
264 | 263 | ||
265 | foreach (UUID ky in removeitems) | 264 | // lock (m_AvatarQueueUUIDMapping) |
266 | { | 265 | // { |
267 | UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; | 266 | // foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) |
268 | m_AvatarQueueUUIDMapping.Remove(ky); | 267 | // { |
269 | 268 | //// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); | |
270 | string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); | 269 | // if (ky == agentID) |
271 | MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); | 270 | // { |
272 | 271 | // removeitems.Add(ky); | |
273 | // m_log.DebugFormat( | 272 | // } |
274 | // "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", | 273 | // } |
275 | // eqgPath, agentID, m_scene.RegionInfo.RegionName); | 274 | // |
276 | } | 275 | // foreach (UUID ky in removeitems) |
277 | } | 276 | // { |
277 | // UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; | ||
278 | // m_AvatarQueueUUIDMapping.Remove(ky); | ||
279 | // | ||
280 | // string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); | ||
281 | // MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); | ||
282 | // | ||
283 | //// m_log.DebugFormat( | ||
284 | //// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", | ||
285 | //// eqgPath, agentID, m_scene.RegionInfo.RegionName); | ||
286 | // } | ||
287 | // } | ||
278 | 288 | ||
279 | UUID searchval = UUID.Zero; | 289 | UUID searchval = UUID.Zero; |
280 | 290 | ||
@@ -359,29 +369,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
359 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); | 369 | m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); |
360 | } | 370 | } |
361 | 371 | ||
362 | string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); | 372 | caps.RegisterPollHandler( |
363 | 373 | "EventQueueGet", | |
364 | // Register this as a caps handler | 374 | new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); |
365 | // FIXME: Confusingly, we need to register separate as a capability so that the client is told about | ||
366 | // EventQueueGet when it receive capability information, but then we replace the rest handler immediately | ||
367 | // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but | ||
368 | // really it should be possible to directly register the poll handler as a capability. | ||
369 | caps.RegisterHandler( | ||
370 | "EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null, "EventQueueGet", null)); | ||
371 | // delegate(Hashtable m_dhttpMethod) | ||
372 | // { | ||
373 | // return ProcessQueue(m_dhttpMethod, agentID, caps); | ||
374 | // })); | ||
375 | |||
376 | // This will persist this beyond the expiry of the caps handlers | ||
377 | // TODO: Add EventQueueGet name/description for diagnostics | ||
378 | MainServer.Instance.AddPollServiceHTTPHandler( | ||
379 | eventQueueGetPath, | ||
380 | new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 40000)); | ||
381 | |||
382 | // m_log.DebugFormat( | ||
383 | // "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", | ||
384 | // eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); | ||
385 | 375 | ||
386 | Random rnd = new Random(Environment.TickCount); | 376 | Random rnd = new Random(Environment.TickCount); |
387 | lock (m_ids) | 377 | lock (m_ids) |
@@ -399,7 +389,10 @@ namespace OpenSim.Region.ClientStack.Linden | |||
399 | Queue<OSD> queue = GetQueue(agentID); | 389 | Queue<OSD> queue = GetQueue(agentID); |
400 | if (queue != null) | 390 | if (queue != null) |
401 | lock (queue) | 391 | lock (queue) |
392 | { | ||
393 | //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count); | ||
402 | return queue.Count > 0; | 394 | return queue.Count > 0; |
395 | } | ||
403 | 396 | ||
404 | return false; | 397 | return false; |
405 | } | 398 | } |
@@ -422,7 +415,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
422 | public Hashtable GetEvents(UUID requestID, UUID pAgentId) | 415 | public Hashtable GetEvents(UUID requestID, UUID pAgentId) |
423 | { | 416 | { |
424 | if (DebugLevel >= 2) | 417 | if (DebugLevel >= 2) |
425 | m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); | 418 | m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); |
426 | 419 | ||
427 | Queue<OSD> queue = TryGetQueue(pAgentId); | 420 | Queue<OSD> queue = TryGetQueue(pAgentId); |
428 | OSD element; | 421 | OSD element; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 6ec1115..7b15284 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | |||
@@ -246,8 +246,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
246 | 246 | ||
247 | private Scene m_scene; | 247 | private Scene m_scene; |
248 | private MeshCapsDataThrottler m_throttler; | 248 | private MeshCapsDataThrottler m_throttler; |
249 | public PollServiceMeshEventArgs(UUID pId, Scene scene) : | 249 | public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : |
250 | base(null, null, null, null, pId, int.MaxValue) | 250 | base(null, uri, null, null, null, pId, int.MaxValue) |
251 | { | 251 | { |
252 | m_scene = scene; | 252 | m_scene = scene; |
253 | m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); | 253 | m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); |
@@ -361,7 +361,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
361 | string capUrl = "/CAPS/" + UUID.Random() + "/"; | 361 | string capUrl = "/CAPS/" + UUID.Random() + "/"; |
362 | 362 | ||
363 | // Register this as a poll service | 363 | // Register this as a poll service |
364 | PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(agentID, m_scene); | 364 | PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene); |
365 | 365 | ||
366 | args.Type = PollServiceEventArgs.EventType.Mesh; | 366 | args.Type = PollServiceEventArgs.EventType.Mesh; |
367 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); | 367 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index a42c96c..c12b8d6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs | |||
@@ -210,7 +210,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
210 | private Scene m_scene; | 210 | private Scene m_scene; |
211 | private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); | 211 | private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); |
212 | public PollServiceTextureEventArgs(UUID pId, Scene scene) : | 212 | public PollServiceTextureEventArgs(UUID pId, Scene scene) : |
213 | base(null, null, null, null, pId, int.MaxValue) | 213 | base(null, "", null, null, null, pId, int.MaxValue) |
214 | { | 214 | { |
215 | m_scene = scene; | 215 | m_scene = scene; |
216 | // x is request id, y is userid | 216 | // x is request id, y is userid |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 27b09a6..f816ad3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -78,7 +78,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
78 | 78 | ||
79 | private static WebFetchInvDescHandler m_webFetchHandler; | 79 | private static WebFetchInvDescHandler m_webFetchHandler; |
80 | 80 | ||
81 | private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); | ||
82 | private static Thread[] m_workerThreads = null; | 81 | private static Thread[] m_workerThreads = null; |
83 | 82 | ||
84 | private static DoubleQueue<aPollRequest> m_queue = | 83 | private static DoubleQueue<aPollRequest> m_queue = |
@@ -115,7 +114,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
115 | return; | 114 | return; |
116 | 115 | ||
117 | m_scene.EventManager.OnRegisterCaps -= RegisterCaps; | 116 | m_scene.EventManager.OnRegisterCaps -= RegisterCaps; |
118 | m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; | ||
119 | 117 | ||
120 | foreach (Thread t in m_workerThreads) | 118 | foreach (Thread t in m_workerThreads) |
121 | Watchdog.AbortThread(t.ManagedThreadId); | 119 | Watchdog.AbortThread(t.ManagedThreadId); |
@@ -135,7 +133,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
135 | m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); | 133 | m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); |
136 | 134 | ||
137 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; | 135 | m_scene.EventManager.OnRegisterCaps += RegisterCaps; |
138 | m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; | ||
139 | 136 | ||
140 | if (m_workerThreads == null) | 137 | if (m_workerThreads == null) |
141 | { | 138 | { |
@@ -178,8 +175,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
178 | 175 | ||
179 | private Scene m_scene; | 176 | private Scene m_scene; |
180 | 177 | ||
181 | public PollServiceInventoryEventArgs(Scene scene, UUID pId) : | 178 | public PollServiceInventoryEventArgs(Scene scene, string url, UUID pId) : |
182 | base(null, null, null, null, pId, int.MaxValue) | 179 | base(null, url, null, null, null, pId, int.MaxValue) |
183 | { | 180 | { |
184 | m_scene = scene; | 181 | m_scene = scene; |
185 | 182 | ||
@@ -310,40 +307,39 @@ namespace OpenSim.Region.ClientStack.Linden | |||
310 | if (m_fetchInventoryDescendents2Url == "") | 307 | if (m_fetchInventoryDescendents2Url == "") |
311 | return; | 308 | return; |
312 | 309 | ||
313 | string capUrl = "/CAPS/" + UUID.Random() + "/"; | ||
314 | |||
315 | // Register this as a poll service | 310 | // Register this as a poll service |
316 | PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID); | 311 | PollServiceInventoryEventArgs args |
317 | 312 | = new PollServiceInventoryEventArgs(m_scene, "/CAPS/" + UUID.Random() + "/", agentID); | |
318 | args.Type = PollServiceEventArgs.EventType.Inventory; | 313 | args.Type = PollServiceEventArgs.EventType.Inventory; |
319 | MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); | ||
320 | |||
321 | string hostName = m_scene.RegionInfo.ExternalHostName; | ||
322 | uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; | ||
323 | string protocol = "http"; | ||
324 | |||
325 | if (MainServer.Instance.UseSSL) | ||
326 | { | ||
327 | hostName = MainServer.Instance.SSLCommonName; | ||
328 | port = MainServer.Instance.SSLPort; | ||
329 | protocol = "https"; | ||
330 | } | ||
331 | |||
332 | caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); | ||
333 | 314 | ||
334 | m_capsDict[agentID] = capUrl; | 315 | caps.RegisterPollHandler("FetchInventoryDescendents2", args); |
316 | |||
317 | // MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); | ||
318 | // | ||
319 | // string hostName = m_scene.RegionInfo.ExternalHostName; | ||
320 | // uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; | ||
321 | // string protocol = "http"; | ||
322 | // | ||
323 | // if (MainServer.Instance.UseSSL) | ||
324 | // { | ||
325 | // hostName = MainServer.Instance.SSLCommonName; | ||
326 | // port = MainServer.Instance.SSLPort; | ||
327 | // protocol = "https"; | ||
328 | // } | ||
329 | // | ||
330 | // caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); | ||
335 | } | 331 | } |
336 | 332 | ||
337 | private void DeregisterCaps(UUID agentID, Caps caps) | 333 | // private void DeregisterCaps(UUID agentID, Caps caps) |
338 | { | 334 | // { |
339 | string capUrl; | 335 | // string capUrl; |
340 | 336 | // | |
341 | if (m_capsDict.TryGetValue(agentID, out capUrl)) | 337 | // if (m_capsDict.TryGetValue(agentID, out capUrl)) |
342 | { | 338 | // { |
343 | MainServer.Instance.RemoveHTTPHandler("", capUrl); | 339 | // MainServer.Instance.RemoveHTTPHandler("", capUrl); |
344 | m_capsDict.Remove(agentID); | 340 | // m_capsDict.Remove(agentID); |
345 | } | 341 | // } |
346 | } | 342 | // } |
347 | 343 | ||
348 | private void DoInventoryRequests() | 344 | private void DoInventoryRequests() |
349 | { | 345 | { |
@@ -353,7 +349,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
353 | 349 | ||
354 | aPollRequest poolreq = m_queue.Dequeue(); | 350 | aPollRequest poolreq = m_queue.Dequeue(); |
355 | 351 | ||
356 | poolreq.thepoll.Process(poolreq); | 352 | if (poolreq != null && poolreq.thepoll != null) |
353 | poolreq.thepoll.Process(poolreq); | ||
357 | } | 354 | } |
358 | } | 355 | } |
359 | } | 356 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index dfad485..ac5e77e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -3816,6 +3816,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3816 | ResendPrimUpdate(update); | 3816 | ResendPrimUpdate(update); |
3817 | } | 3817 | } |
3818 | 3818 | ||
3819 | // OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | ||
3820 | // OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); | ||
3821 | // OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | ||
3822 | // OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | ||
3823 | // | ||
3824 | // OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3825 | // OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3826 | // OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3827 | // OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3828 | |||
3829 | |||
3819 | private void ProcessEntityUpdates(int maxUpdates) | 3830 | private void ProcessEntityUpdates(int maxUpdates) |
3820 | { | 3831 | { |
3821 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | 3832 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); |
@@ -3828,6 +3839,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3828 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | 3839 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); |
3829 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | 3840 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); |
3830 | 3841 | ||
3842 | // objectUpdateBlocks.Value.Clear(); | ||
3843 | // compressedUpdateBlocks.Value.Clear(); | ||
3844 | // terseUpdateBlocks.Value.Clear(); | ||
3845 | // terseAgentUpdateBlocks.Value.Clear(); | ||
3846 | // objectUpdates.Value.Clear(); | ||
3847 | // compressedUpdates.Value.Clear(); | ||
3848 | // terseUpdates.Value.Clear(); | ||
3849 | // terseAgentUpdates.Value.Clear(); | ||
3850 | |||
3831 | // Check to see if this is a flush | 3851 | // Check to see if this is a flush |
3832 | if (maxUpdates <= 0) | 3852 | if (maxUpdates <= 0) |
3833 | { | 3853 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 77b07ed..b4ac021 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -809,8 +809,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
809 | } | 809 | } |
810 | 810 | ||
811 | PacketPool.Instance.ReturnPacket(packet); | 811 | PacketPool.Instance.ReturnPacket(packet); |
812 | m_dataPresentEvent.Set(); | ||
813 | |||
812 | } | 814 | } |
813 | 815 | ||
816 | private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false); | ||
817 | |||
814 | /// <summary> | 818 | /// <summary> |
815 | /// Start the process of sending a packet to the client. | 819 | /// Start the process of sending a packet to the client. |
816 | /// </summary> | 820 | /// </summary> |
@@ -1730,6 +1734,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1730 | // Action generic every round | 1734 | // Action generic every round |
1731 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; | 1735 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; |
1732 | 1736 | ||
1737 | // while (true) | ||
1733 | while (base.IsRunningOutbound) | 1738 | while (base.IsRunningOutbound) |
1734 | { | 1739 | { |
1735 | m_scene.ThreadAlive(2); | 1740 | m_scene.ThreadAlive(2); |
@@ -1791,8 +1796,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1791 | 1796 | ||
1792 | // If nothing was sent, sleep for the minimum amount of time before a | 1797 | // If nothing was sent, sleep for the minimum amount of time before a |
1793 | // token bucket could get more tokens | 1798 | // token bucket could get more tokens |
1794 | if (!m_packetSent) | 1799 | //if (!m_packetSent) |
1795 | Thread.Sleep((int)TickCountResolution); | 1800 | // Thread.Sleep((int)TickCountResolution); |
1801 | m_dataPresentEvent.WaitOne(100); | ||
1796 | 1802 | ||
1797 | Watchdog.UpdateThread(); | 1803 | Watchdog.UpdateThread(); |
1798 | } | 1804 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a60b314..505bb53 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -75,10 +75,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
75 | public void AddRegion(Scene scene) | 75 | public void AddRegion(Scene scene) |
76 | { | 76 | { |
77 | m_scene = scene; | 77 | m_scene = scene; |
78 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | ||
79 | |||
80 | if (Enabled) | 78 | if (Enabled) |
81 | { | 79 | { |
80 | // Only register module with scene if it is enabled. All callers check for a null attachments module. | ||
81 | // Ideally, there should be a null attachments module for when this core attachments module has been | ||
82 | // disabled. Registering only when enabled allows for other attachments module implementations. | ||
83 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | ||
82 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 84 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
83 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); | 85 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); |
84 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); | 86 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); |
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index 6ce6227..0c759df 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs | |||
@@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.Framework | |||
80 | 80 | ||
81 | MainConsole.Instance.Commands.AddCommand( | 81 | MainConsole.Instance.Commands.AddCommand( |
82 | "Comms", false, "show caps stats by user", | 82 | "Comms", false, "show caps stats by user", |
83 | "show caps stats [<first-name> <last-name>]", | 83 | "show caps stats by user [<first-name> <last-name>]", |
84 | "Shows statistics on capabilities use by user.", | 84 | "Shows statistics on capabilities use by user.", |
85 | "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.", | 85 | "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.", |
86 | HandleShowCapsStatsByUserCommand); | 86 | HandleShowCapsStatsByUserCommand); |
@@ -296,27 +296,31 @@ namespace OpenSim.Region.CoreModules.Framework | |||
296 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) | 296 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) |
297 | return; | 297 | return; |
298 | 298 | ||
299 | StringBuilder caps = new StringBuilder(); | 299 | StringBuilder capsReport = new StringBuilder(); |
300 | caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); | 300 | capsReport.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); |
301 | 301 | ||
302 | lock (m_capsObjects) | 302 | lock (m_capsObjects) |
303 | { | 303 | { |
304 | foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects) | 304 | foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects) |
305 | { | 305 | { |
306 | caps.AppendFormat("** Circuit {0}:\n", kvp.Key); | 306 | capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key); |
307 | Caps caps = kvp.Value; | ||
307 | 308 | ||
308 | for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) | 309 | for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) |
309 | { | 310 | { |
310 | Uri uri = new Uri(kvp2.Value.ToString()); | 311 | Uri uri = new Uri(kvp2.Value.ToString()); |
311 | caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); | 312 | capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); |
312 | } | 313 | } |
313 | 314 | ||
314 | foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers) | 315 | foreach (KeyValuePair<string, PollServiceEventArgs> kvp2 in caps.GetPollHandlers()) |
315 | caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); | 316 | capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url); |
317 | |||
318 | foreach (KeyValuePair<string, string> kvp3 in caps.ExternalCapsHandlers) | ||
319 | capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); | ||
316 | } | 320 | } |
317 | } | 321 | } |
318 | 322 | ||
319 | MainConsole.Instance.Output(caps.ToString()); | 323 | MainConsole.Instance.Output(capsReport.ToString()); |
320 | } | 324 | } |
321 | 325 | ||
322 | private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams) | 326 | private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams) |
@@ -374,7 +378,16 @@ namespace OpenSim.Region.CoreModules.Framework | |||
374 | { | 378 | { |
375 | receivedStats[sp.Name] = reqHandler.RequestsReceived; | 379 | receivedStats[sp.Name] = reqHandler.RequestsReceived; |
376 | handledStats[sp.Name] = reqHandler.RequestsHandled; | 380 | handledStats[sp.Name] = reqHandler.RequestsHandled; |
377 | } | 381 | } |
382 | else | ||
383 | { | ||
384 | PollServiceEventArgs pollHandler = null; | ||
385 | if (caps.TryGetPollHandler(capName, out pollHandler)) | ||
386 | { | ||
387 | receivedStats[sp.Name] = pollHandler.RequestsReceived; | ||
388 | handledStats[sp.Name] = pollHandler.RequestsHandled; | ||
389 | } | ||
390 | } | ||
378 | } | 391 | } |
379 | ); | 392 | ); |
380 | 393 | ||
@@ -405,11 +418,9 @@ namespace OpenSim.Region.CoreModules.Framework | |||
405 | Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); | 418 | Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); |
406 | 419 | ||
407 | if (caps == null) | 420 | if (caps == null) |
408 | return; | 421 | return; |
409 | |||
410 | Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers(); | ||
411 | 422 | ||
412 | foreach (IRequestHandler reqHandler in capsHandlers.Values) | 423 | foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values) |
413 | { | 424 | { |
414 | string reqName = reqHandler.Name ?? ""; | 425 | string reqName = reqHandler.Name ?? ""; |
415 | 426 | ||
@@ -424,6 +435,23 @@ namespace OpenSim.Region.CoreModules.Framework | |||
424 | handledStats[reqName] += reqHandler.RequestsHandled; | 435 | handledStats[reqName] += reqHandler.RequestsHandled; |
425 | } | 436 | } |
426 | } | 437 | } |
438 | |||
439 | foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers()) | ||
440 | { | ||
441 | string name = kvp.Key; | ||
442 | PollServiceEventArgs pollHandler = kvp.Value; | ||
443 | |||
444 | if (!receivedStats.ContainsKey(name)) | ||
445 | { | ||
446 | receivedStats[name] = pollHandler.RequestsReceived; | ||
447 | handledStats[name] = pollHandler.RequestsHandled; | ||
448 | } | ||
449 | else | ||
450 | { | ||
451 | receivedStats[name] += pollHandler.RequestsReceived; | ||
452 | handledStats[name] += pollHandler.RequestsHandled; | ||
453 | } | ||
454 | } | ||
427 | } | 455 | } |
428 | ); | 456 | ); |
429 | 457 | ||
@@ -486,12 +514,16 @@ namespace OpenSim.Region.CoreModules.Framework | |||
486 | if (caps == null) | 514 | if (caps == null) |
487 | return; | 515 | return; |
488 | 516 | ||
489 | Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers(); | 517 | List<CapTableRow> capRows = new List<CapTableRow>(); |
490 | 518 | ||
491 | foreach (IRequestHandler reqHandler in capsHandlers.Values.OrderByDescending(rh => rh.RequestsReceived)) | 519 | foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values) |
492 | { | 520 | capRows.Add(new CapTableRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled)); |
493 | cdt.AddRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled); | 521 | |
494 | } | 522 | foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers()) |
523 | capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled)); | ||
524 | |||
525 | foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived)) | ||
526 | cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled); | ||
495 | 527 | ||
496 | sb.Append(cdt.ToString()); | 528 | sb.Append(cdt.ToString()); |
497 | */ | 529 | */ |
@@ -525,6 +557,14 @@ namespace OpenSim.Region.CoreModules.Framework | |||
525 | totalRequestsReceived += reqHandler.RequestsReceived; | 557 | totalRequestsReceived += reqHandler.RequestsReceived; |
526 | totalRequestsHandled += reqHandler.RequestsHandled; | 558 | totalRequestsHandled += reqHandler.RequestsHandled; |
527 | } | 559 | } |
560 | |||
561 | Dictionary<string, PollServiceEventArgs> capsPollHandlers = caps.GetPollHandlers(); | ||
562 | |||
563 | foreach (PollServiceEventArgs handler in capsPollHandlers.Values) | ||
564 | { | ||
565 | totalRequestsReceived += handler.RequestsReceived; | ||
566 | totalRequestsHandled += handler.RequestsHandled; | ||
567 | } | ||
528 | 568 | ||
529 | cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled); | 569 | cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled); |
530 | } | 570 | } |
@@ -533,5 +573,19 @@ namespace OpenSim.Region.CoreModules.Framework | |||
533 | sb.Append(cdt.ToString()); | 573 | sb.Append(cdt.ToString()); |
534 | */ | 574 | */ |
535 | } | 575 | } |
576 | |||
577 | private class CapTableRow | ||
578 | { | ||
579 | public string Name { get; set; } | ||
580 | public int RequestsReceived { get; set; } | ||
581 | public int RequestsHandled { get; set; } | ||
582 | |||
583 | public CapTableRow(string name, int requestsReceived, int requestsHandled) | ||
584 | { | ||
585 | Name = name; | ||
586 | RequestsReceived = requestsReceived; | ||
587 | RequestsHandled = requestsHandled; | ||
588 | } | ||
589 | } | ||
536 | } | 590 | } |
537 | } | 591 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs index f1eb1ad..a70261e 100644 --- a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs | |||
@@ -42,23 +42,37 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; | |||
42 | namespace OpenSim.Region.CoreModules.Framework | 42 | namespace OpenSim.Region.CoreModules.Framework |
43 | { | 43 | { |
44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")] | 44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")] |
45 | public class GridServiceThrottleModule : ISharedRegionModule | 45 | public class ServiceThrottleModule : ISharedRegionModule, IServiceThrottleModule |
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger( | 47 | private static readonly ILog m_log = LogManager.GetLogger( |
48 | MethodBase.GetCurrentMethod().DeclaringType); | 48 | MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private readonly List<Scene> m_scenes = new List<Scene>(); | 50 | private readonly List<Scene> m_scenes = new List<Scene>(); |
51 | private System.Timers.Timer m_timer = new System.Timers.Timer(); | ||
51 | 52 | ||
52 | private OpenSim.Framework.BlockingQueue<GridRegionRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<GridRegionRequest>(); | 53 | private Queue<Action> m_RequestQueue = new Queue<Action>(); |
54 | private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>(); | ||
55 | private int m_Interval; | ||
56 | |||
57 | #region ISharedRegionModule | ||
53 | 58 | ||
54 | public void Initialise(IConfigSource config) | 59 | public void Initialise(IConfigSource config) |
55 | { | 60 | { |
56 | Watchdog.StartThread( | 61 | m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000); |
57 | ProcessQueue, | 62 | |
58 | "GridServiceRequestThread", | 63 | m_timer = new System.Timers.Timer(); |
59 | ThreadPriority.BelowNormal, | 64 | m_timer.AutoReset = false; |
60 | true, | 65 | m_timer.Enabled = true; |
61 | false); | 66 | m_timer.Interval = 15000; // 15 secs at first |
67 | m_timer.Elapsed += ProcessQueue; | ||
68 | m_timer.Start(); | ||
69 | |||
70 | //Watchdog.StartThread( | ||
71 | // ProcessQueue, | ||
72 | // "GridServiceRequestThread", | ||
73 | // ThreadPriority.BelowNormal, | ||
74 | // true, | ||
75 | // false); | ||
62 | } | 76 | } |
63 | 77 | ||
64 | public void AddRegion(Scene scene) | 78 | public void AddRegion(Scene scene) |
@@ -66,7 +80,9 @@ namespace OpenSim.Region.CoreModules.Framework | |||
66 | lock (m_scenes) | 80 | lock (m_scenes) |
67 | { | 81 | { |
68 | m_scenes.Add(scene); | 82 | m_scenes.Add(scene); |
83 | scene.RegisterModuleInterface<IServiceThrottleModule>(this); | ||
69 | scene.EventManager.OnNewClient += OnNewClient; | 84 | scene.EventManager.OnNewClient += OnNewClient; |
85 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; | ||
70 | } | 86 | } |
71 | } | 87 | } |
72 | 88 | ||
@@ -83,11 +99,6 @@ namespace OpenSim.Region.CoreModules.Framework | |||
83 | } | 99 | } |
84 | } | 100 | } |
85 | 101 | ||
86 | void OnNewClient(IClientAPI client) | ||
87 | { | ||
88 | client.OnRegionHandleRequest += OnRegionHandleRequest; | ||
89 | } | ||
90 | |||
91 | public void PostInitialise() | 102 | public void PostInitialise() |
92 | { | 103 | { |
93 | } | 104 | } |
@@ -98,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework | |||
98 | 109 | ||
99 | public string Name | 110 | public string Name |
100 | { | 111 | { |
101 | get { return "GridServiceThrottleModule"; } | 112 | get { return "ServiceThrottleModule"; } |
102 | } | 113 | } |
103 | 114 | ||
104 | public Type ReplaceableInterface | 115 | public Type ReplaceableInterface |
@@ -106,9 +117,31 @@ namespace OpenSim.Region.CoreModules.Framework | |||
106 | get { return null; } | 117 | get { return null; } |
107 | } | 118 | } |
108 | 119 | ||
120 | #endregion ISharedRegionMOdule | ||
121 | |||
122 | #region Events | ||
123 | |||
124 | void OnNewClient(IClientAPI client) | ||
125 | { | ||
126 | client.OnRegionHandleRequest += OnRegionHandleRequest; | ||
127 | } | ||
128 | |||
129 | void OnMakeRootAgent(ScenePresence obj) | ||
130 | { | ||
131 | lock (m_timer) | ||
132 | { | ||
133 | if (!m_timer.Enabled) | ||
134 | { | ||
135 | m_timer.Interval = m_Interval; | ||
136 | m_timer.Enabled = true; | ||
137 | m_timer.Start(); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
109 | public void OnRegionHandleRequest(IClientAPI client, UUID regionID) | 142 | public void OnRegionHandleRequest(IClientAPI client, UUID regionID) |
110 | { | 143 | { |
111 | //m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID); | 144 | //m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID); |
112 | ulong handle = 0; | 145 | ulong handle = 0; |
113 | if (IsLocalRegionHandle(regionID, out handle)) | 146 | if (IsLocalRegionHandle(regionID, out handle)) |
114 | { | 147 | { |
@@ -116,11 +149,83 @@ namespace OpenSim.Region.CoreModules.Framework | |||
116 | return; | 149 | return; |
117 | } | 150 | } |
118 | 151 | ||
119 | GridRegionRequest request = new GridRegionRequest(client, regionID); | 152 | Action action = delegate |
120 | m_RequestQueue.Enqueue(request); | 153 | { |
154 | GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID); | ||
155 | |||
156 | if (r != null && r.RegionHandle != 0) | ||
157 | client.SendRegionHandle(regionID, r.RegionHandle); | ||
158 | }; | ||
159 | |||
160 | Enqueue("region", regionID.ToString(), action); | ||
161 | } | ||
162 | |||
163 | #endregion Events | ||
164 | |||
165 | #region IServiceThrottleModule | ||
166 | |||
167 | public void Enqueue(string category, string itemid, Action continuation) | ||
168 | { | ||
169 | lock (m_RequestQueue) | ||
170 | { | ||
171 | if (m_Pending.ContainsKey(category)) | ||
172 | { | ||
173 | if (m_Pending[category].Contains(itemid)) | ||
174 | // Don't enqueue, it's already pending | ||
175 | return; | ||
176 | } | ||
177 | else | ||
178 | m_Pending.Add(category, new List<string>()); | ||
179 | |||
180 | m_Pending[category].Add(itemid); | ||
181 | |||
182 | m_RequestQueue.Enqueue(delegate | ||
183 | { | ||
184 | lock (m_RequestQueue) | ||
185 | m_Pending[category].Remove(itemid); | ||
186 | |||
187 | continuation(); | ||
188 | }); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | #endregion IServiceThrottleModule | ||
193 | |||
194 | #region Process Continuation Queue | ||
195 | |||
196 | private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e) | ||
197 | { | ||
198 | //m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count); | ||
199 | |||
200 | while (m_RequestQueue.Count > 0) | ||
201 | { | ||
202 | Action continuation = null; | ||
203 | lock (m_RequestQueue) | ||
204 | continuation = m_RequestQueue.Dequeue(); | ||
205 | |||
206 | if (continuation != null) | ||
207 | continuation(); | ||
208 | } | ||
209 | |||
210 | if (AreThereRootAgents()) | ||
211 | { | ||
212 | lock (m_timer) | ||
213 | { | ||
214 | m_timer.Interval = 1000; // 1 sec | ||
215 | m_timer.Enabled = true; | ||
216 | m_timer.Start(); | ||
217 | } | ||
218 | } | ||
219 | else | ||
220 | lock (m_timer) | ||
221 | m_timer.Enabled = false; | ||
121 | 222 | ||
122 | } | 223 | } |
123 | 224 | ||
225 | #endregion Process Continuation Queue | ||
226 | |||
227 | #region Misc | ||
228 | |||
124 | private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle) | 229 | private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle) |
125 | { | 230 | { |
126 | regionHandle = 0; | 231 | regionHandle = 0; |
@@ -133,31 +238,19 @@ namespace OpenSim.Region.CoreModules.Framework | |||
133 | return false; | 238 | return false; |
134 | } | 239 | } |
135 | 240 | ||
136 | private void ProcessQueue() | 241 | private bool AreThereRootAgents() |
137 | { | 242 | { |
138 | while (true) | 243 | foreach (Scene s in m_scenes) |
139 | { | 244 | { |
140 | Watchdog.UpdateThread(); | 245 | foreach (ScenePresence sp in s.GetScenePresences()) |
141 | 246 | if (!sp.IsChildAgent) | |
142 | GridRegionRequest request = m_RequestQueue.Dequeue(); | 247 | return true; |
143 | GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID); | ||
144 | |||
145 | if (r != null && r.RegionHandle != 0) | ||
146 | request.client.SendRegionHandle(request.regionID, r.RegionHandle); | ||
147 | |||
148 | } | 248 | } |
149 | } | ||
150 | } | ||
151 | |||
152 | class GridRegionRequest | ||
153 | { | ||
154 | public IClientAPI client; | ||
155 | public UUID regionID; | ||
156 | 249 | ||
157 | public GridRegionRequest(IClientAPI c, UUID r) | 250 | return false; |
158 | { | ||
159 | client = c; | ||
160 | regionID = r; | ||
161 | } | 251 | } |
252 | |||
253 | #endregion Misc | ||
162 | } | 254 | } |
255 | |||
163 | } | 256 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index a528093..a91adfa 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -56,13 +56,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
56 | protected bool m_Enabled; | 56 | protected bool m_Enabled; |
57 | protected List<Scene> m_Scenes = new List<Scene>(); | 57 | protected List<Scene> m_Scenes = new List<Scene>(); |
58 | 58 | ||
59 | protected IServiceThrottleModule m_ServiceThrottle; | ||
59 | // The cache | 60 | // The cache |
60 | protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); | 61 | protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); |
61 | 62 | ||
62 | // Throttle the name requests | ||
63 | private OpenSim.Framework.BlockingQueue<NameRequest> m_RequestQueue = new OpenSim.Framework.BlockingQueue<NameRequest>(); | ||
64 | |||
65 | |||
66 | #region ISharedRegionModule | 63 | #region ISharedRegionModule |
67 | 64 | ||
68 | public void Initialise(IConfigSource config) | 65 | public void Initialise(IConfigSource config) |
@@ -115,6 +112,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
115 | 112 | ||
116 | public void RegionLoaded(Scene s) | 113 | public void RegionLoaded(Scene s) |
117 | { | 114 | { |
115 | if (m_Enabled && m_ServiceThrottle == null) | ||
116 | m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>(); | ||
118 | } | 117 | } |
119 | 118 | ||
120 | public void PostInitialise() | 119 | public void PostInitialise() |
@@ -154,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
154 | client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); | 153 | client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); |
155 | } | 154 | } |
156 | 155 | ||
157 | void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) | 156 | void HandleUUIDNameRequest(UUID uuid, IClientAPI client) |
158 | { | 157 | { |
159 | // m_log.DebugFormat( | 158 | // m_log.DebugFormat( |
160 | // "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", | 159 | // "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", |
@@ -162,12 +161,31 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
162 | 161 | ||
163 | if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) | 162 | if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) |
164 | { | 163 | { |
165 | remote_client.SendNameReply(uuid, "Mr", "OpenSim"); | 164 | client.SendNameReply(uuid, "Mr", "OpenSim"); |
166 | } | 165 | } |
167 | else | 166 | else |
168 | { | 167 | { |
169 | NameRequest request = new NameRequest(remote_client, uuid); | 168 | string[] names = new string[2]; |
170 | m_RequestQueue.Enqueue(request); | 169 | if (TryGetUserNamesFromCache(uuid, names)) |
170 | { | ||
171 | client.SendNameReply(uuid, names[0], names[1]); | ||
172 | return; | ||
173 | } | ||
174 | |||
175 | // Not found in cache, queue continuation | ||
176 | m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate | ||
177 | { | ||
178 | //m_log.DebugFormat("[YYY]: Name request {0}", uuid); | ||
179 | bool foundRealName = TryGetUserNames(uuid, names); | ||
180 | |||
181 | if (names.Length == 2) | ||
182 | { | ||
183 | if (!foundRealName) | ||
184 | 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); | ||
185 | |||
186 | client.SendNameReply(uuid, names[0], names[1]); | ||
187 | } | ||
188 | }); | ||
171 | 189 | ||
172 | } | 190 | } |
173 | } | 191 | } |
@@ -283,15 +301,27 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
283 | } | 301 | } |
284 | 302 | ||
285 | /// <summary> | 303 | /// <summary> |
286 | /// Try to get the names bound to the given uuid. | 304 | /// |
287 | /// </summary> | 305 | /// </summary> |
288 | /// <returns>True if the name was found, false if not.</returns> | 306 | /// <param name="uuid"></param> |
289 | /// <param name='uuid'></param> | 307 | /// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param> |
290 | /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param> | 308 | /// <returns></returns> |
291 | private bool TryGetUserNames(UUID uuid, out string[] names) | 309 | private bool TryGetUserNames(UUID uuid, string[] names) |
292 | { | 310 | { |
293 | names = new string[2]; | 311 | if (names == null) |
312 | names = new string[2]; | ||
313 | |||
314 | if (TryGetUserNamesFromCache(uuid, names)) | ||
315 | return true; | ||
316 | |||
317 | if (TryGetUserNamesFromServices(uuid, names)) | ||
318 | return true; | ||
319 | |||
320 | return false; | ||
321 | } | ||
294 | 322 | ||
323 | private bool TryGetUserNamesFromCache(UUID uuid, string[] names) | ||
324 | { | ||
295 | lock (m_UserCache) | 325 | lock (m_UserCache) |
296 | { | 326 | { |
297 | if (m_UserCache.ContainsKey(uuid)) | 327 | if (m_UserCache.ContainsKey(uuid)) |
@@ -303,6 +333,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
303 | } | 333 | } |
304 | } | 334 | } |
305 | 335 | ||
336 | return false; | ||
337 | } | ||
338 | |||
339 | /// <summary> | ||
340 | /// Try to get the names bound to the given uuid, from the services. | ||
341 | /// </summary> | ||
342 | /// <returns>True if the name was found, false if not.</returns> | ||
343 | /// <param name='uuid'></param> | ||
344 | /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param> | ||
345 | private bool TryGetUserNamesFromServices(UUID uuid, string[] names) | ||
346 | { | ||
306 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); | 347 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); |
307 | 348 | ||
308 | if (account != null) | 349 | if (account != null) |
@@ -387,18 +428,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
387 | 428 | ||
388 | public string GetUserName(UUID uuid) | 429 | public string GetUserName(UUID uuid) |
389 | { | 430 | { |
390 | string[] names; | 431 | string[] names = new string[2]; |
391 | TryGetUserNames(uuid, out names); | 432 | TryGetUserNames(uuid, names); |
392 | 433 | ||
393 | if (names.Length == 2) | 434 | return names[0] + " " + names[1]; |
394 | { | ||
395 | string firstname = names[0]; | ||
396 | string lastname = names[1]; | ||
397 | |||
398 | return firstname + " " + lastname; | ||
399 | } | ||
400 | 435 | ||
401 | return "(hippos)"; | ||
402 | } | 436 | } |
403 | 437 | ||
404 | public string GetUserHomeURL(UUID userID) | 438 | public string GetUserHomeURL(UUID userID) |
@@ -598,13 +632,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
598 | protected void Init() | 632 | protected void Init() |
599 | { | 633 | { |
600 | RegisterConsoleCmds(); | 634 | RegisterConsoleCmds(); |
601 | Watchdog.StartThread( | ||
602 | ProcessQueue, | ||
603 | "NameRequestThread", | ||
604 | ThreadPriority.BelowNormal, | ||
605 | true, | ||
606 | false); | ||
607 | |||
608 | } | 635 | } |
609 | 636 | ||
610 | protected void RegisterConsoleCmds() | 637 | protected void RegisterConsoleCmds() |
@@ -674,39 +701,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
674 | MainConsole.Instance.Output(cdt.ToString()); | 701 | MainConsole.Instance.Output(cdt.ToString()); |
675 | } | 702 | } |
676 | 703 | ||
677 | private void ProcessQueue() | ||
678 | { | ||
679 | while (true) | ||
680 | { | ||
681 | Watchdog.UpdateThread(); | ||
682 | |||
683 | NameRequest request = m_RequestQueue.Dequeue(); | ||
684 | string[] names; | ||
685 | bool foundRealName = TryGetUserNames(request.uuid, out names); | ||
686 | |||
687 | if (names.Length == 2) | ||
688 | { | ||
689 | if (!foundRealName) | ||
690 | 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); | ||
691 | |||
692 | request.client.SendNameReply(request.uuid, names[0], names[1]); | ||
693 | } | ||
694 | |||
695 | } | ||
696 | } | ||
697 | |||
698 | } | ||
699 | |||
700 | class NameRequest | ||
701 | { | ||
702 | public IClientAPI client; | ||
703 | public UUID uuid; | ||
704 | |||
705 | public NameRequest(IClientAPI c, UUID n) | ||
706 | { | ||
707 | client = c; | ||
708 | uuid = n; | ||
709 | } | ||
710 | } | 704 | } |
711 | 705 | ||
712 | } \ No newline at end of file | 706 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 2a4d440..1983fed 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | |||
@@ -219,7 +219,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
219 | 219 | ||
220 | string uri = "/lslhttp/" + urlcode.ToString(); | 220 | string uri = "/lslhttp/" + urlcode.ToString(); |
221 | 221 | ||
222 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); | 222 | PollServiceEventArgs args |
223 | = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); | ||
223 | args.Type = PollServiceEventArgs.EventType.LslHttp; | 224 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
224 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); | 225 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); |
225 | 226 | ||
@@ -266,7 +267,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
266 | 267 | ||
267 | string uri = "/lslhttps/" + urlcode.ToString(); | 268 | string uri = "/lslhttps/" + urlcode.ToString(); |
268 | 269 | ||
269 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); | 270 | PollServiceEventArgs args |
271 | = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); | ||
270 | args.Type = PollServiceEventArgs.EventType.LslHttp; | 272 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
271 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); | 273 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); |
272 | 274 | ||
diff --git a/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs new file mode 100644 index 0000000..198256f --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IServiceThrottleModule.cs | |||
@@ -0,0 +1,19 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | |||
4 | namespace OpenSim.Region.Framework.Interfaces | ||
5 | { | ||
6 | public interface IServiceThrottleModule | ||
7 | { | ||
8 | /// <summary> | ||
9 | /// Enqueue a continuation meant to get a resource from elsewhere. | ||
10 | /// As usual with CPS, caller beware: if that continuation is a never-ending computation, | ||
11 | /// the whole thread will be blocked, and no requests are processed | ||
12 | /// </summary> | ||
13 | /// <param name="category">Category of the resource (e.g. name, region)</param> | ||
14 | /// <param name="itemid">The resource identifier</param> | ||
15 | /// <param name="continuation">The continuation to be executed</param> | ||
16 | void Enqueue(string category, string itemid, Action continuation); | ||
17 | } | ||
18 | |||
19 | } | ||
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 8c9c006..b0a29c0 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | |||
@@ -116,7 +116,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
116 | return false; | 116 | return false; |
117 | 117 | ||
118 | // Delete existing npc attachments | 118 | // Delete existing npc attachments |
119 | scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false); | 119 | if(scene.AttachmentsModule != null) |
120 | scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false); | ||
120 | 121 | ||
121 | // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet | 122 | // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet |
122 | // since it doesn't transfer attachments | 123 | // since it doesn't transfer attachments |
@@ -125,7 +126,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
125 | npc.Appearance = npcAppearance; | 126 | npc.Appearance = npcAppearance; |
126 | 127 | ||
127 | // Rez needed npc attachments | 128 | // Rez needed npc attachments |
128 | scene.AttachmentsModule.RezAttachments(npc); | 129 | if (scene.AttachmentsModule != null) |
130 | scene.AttachmentsModule.RezAttachments(npc); | ||
129 | 131 | ||
130 | IAvatarFactoryModule module = | 132 | IAvatarFactoryModule module = |
131 | scene.RequestModuleInterface<IAvatarFactoryModule>(); | 133 | scene.RequestModuleInterface<IAvatarFactoryModule>(); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs index 928b350..0f11c4a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs | |||
@@ -130,6 +130,7 @@ public class BSActorAvatarMove : BSActor | |||
130 | SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); | 130 | SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */); |
131 | 131 | ||
132 | m_physicsScene.BeforeStep += Mover; | 132 | m_physicsScene.BeforeStep += Mover; |
133 | m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; | ||
133 | 134 | ||
134 | m_walkingUpStairs = 0; | 135 | m_walkingUpStairs = 0; |
135 | } | 136 | } |
@@ -139,6 +140,7 @@ public class BSActorAvatarMove : BSActor | |||
139 | { | 140 | { |
140 | if (m_velocityMotor != null) | 141 | if (m_velocityMotor != null) |
141 | { | 142 | { |
143 | m_controllingPrim.OnPreUpdateProperty -= Process_OnPreUpdateProperty; | ||
142 | m_physicsScene.BeforeStep -= Mover; | 144 | m_physicsScene.BeforeStep -= Mover; |
143 | m_velocityMotor = null; | 145 | m_velocityMotor = null; |
144 | } | 146 | } |
@@ -197,7 +199,7 @@ public class BSActorAvatarMove : BSActor | |||
197 | { | 199 | { |
198 | if (m_controllingPrim.Flying) | 200 | if (m_controllingPrim.Flying) |
199 | { | 201 | { |
200 | // Flying and not collising and velocity nearly zero. | 202 | // Flying and not colliding and velocity nearly zero. |
201 | m_controllingPrim.ZeroMotion(true /* inTaintTime */); | 203 | m_controllingPrim.ZeroMotion(true /* inTaintTime */); |
202 | } | 204 | } |
203 | } | 205 | } |
@@ -266,6 +268,19 @@ public class BSActorAvatarMove : BSActor | |||
266 | } | 268 | } |
267 | } | 269 | } |
268 | 270 | ||
271 | // Called just as the property update is received from the physics engine. | ||
272 | // Do any mode necessary for avatar movement. | ||
273 | private void Process_OnPreUpdateProperty(ref EntityProperties entprop) | ||
274 | { | ||
275 | // Don't change position if standing on a stationary object. | ||
276 | if (m_controllingPrim.IsStationary) | ||
277 | { | ||
278 | entprop.Position = m_controllingPrim.RawPosition; | ||
279 | m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation); | ||
280 | } | ||
281 | |||
282 | } | ||
283 | |||
269 | // Decide if the character is colliding with a low object and compute a force to pop the | 284 | // Decide if the character is colliding with a low object and compute a force to pop the |
270 | // avatar up so it can walk up and over the low objects. | 285 | // avatar up so it can walk up and over the low objects. |
271 | private OMV.Vector3 WalkUpStairs() | 286 | private OMV.Vector3 WalkUpStairs() |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c9e3ca0..59e7f5f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -709,10 +709,10 @@ public sealed class BSCharacter : BSPhysObject | |||
709 | // the world that things have changed. | 709 | // the world that things have changed. |
710 | public override void UpdateProperties(EntityProperties entprop) | 710 | public override void UpdateProperties(EntityProperties entprop) |
711 | { | 711 | { |
712 | // Don't change position if standing on a stationary object. | 712 | // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. |
713 | if (!IsStationary) | 713 | TriggerPreUpdatePropertyAction(ref entprop); |
714 | RawPosition = entprop.Position; | ||
715 | 714 | ||
715 | RawPosition = entprop.Position; | ||
716 | RawOrientation = entprop.Rotation; | 716 | RawOrientation = entprop.Rotation; |
717 | 717 | ||
718 | // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar | 718 | // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar |
@@ -740,7 +740,7 @@ public sealed class BSCharacter : BSPhysObject | |||
740 | // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); | 740 | // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); |
741 | 741 | ||
742 | // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. | 742 | // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. |
743 | // base.RequestPhysicsterseUpdate(); | 743 | // PhysScene.PostUpdate(this); |
744 | 744 | ||
745 | DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | 745 | DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", |
746 | LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); | 746 | LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index a41eaf8..fc4545f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -103,9 +103,10 @@ public abstract class BSPhysObject : PhysicsActor | |||
103 | CollisionsLastTickStep = -1; | 103 | CollisionsLastTickStep = -1; |
104 | 104 | ||
105 | SubscribedEventsMs = 0; | 105 | SubscribedEventsMs = 0; |
106 | CollidingStep = 0; | 106 | // Crazy values that will never be true |
107 | CollidingGroundStep = 0; | 107 | CollidingStep = BSScene.NotASimulationStep; |
108 | CollisionAccumulation = 0; | 108 | CollidingGroundStep = BSScene.NotASimulationStep; |
109 | CollisionAccumulation = BSScene.NotASimulationStep; | ||
109 | ColliderIsMoving = false; | 110 | ColliderIsMoving = false; |
110 | CollisionScore = 0; | 111 | CollisionScore = 0; |
111 | 112 | ||
@@ -349,7 +350,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
349 | if (value) | 350 | if (value) |
350 | CollidingStep = PhysScene.SimulationStep; | 351 | CollidingStep = PhysScene.SimulationStep; |
351 | else | 352 | else |
352 | CollidingStep = 0; | 353 | CollidingStep = BSScene.NotASimulationStep; |
353 | } | 354 | } |
354 | } | 355 | } |
355 | public override bool CollidingGround { | 356 | public override bool CollidingGround { |
@@ -359,7 +360,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
359 | if (value) | 360 | if (value) |
360 | CollidingGroundStep = PhysScene.SimulationStep; | 361 | CollidingGroundStep = PhysScene.SimulationStep; |
361 | else | 362 | else |
362 | CollidingGroundStep = 0; | 363 | CollidingGroundStep = BSScene.NotASimulationStep; |
363 | } | 364 | } |
364 | } | 365 | } |
365 | public override bool CollidingObj { | 366 | public override bool CollidingObj { |
@@ -368,7 +369,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
368 | if (value) | 369 | if (value) |
369 | CollidingObjectStep = PhysScene.SimulationStep; | 370 | CollidingObjectStep = PhysScene.SimulationStep; |
370 | else | 371 | else |
371 | CollidingObjectStep = 0; | 372 | CollidingObjectStep = BSScene.NotASimulationStep; |
372 | } | 373 | } |
373 | } | 374 | } |
374 | 375 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 214271b..41aca3b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -97,6 +97,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
97 | 97 | ||
98 | internal long m_simulationStep = 0; // The current simulation step. | 98 | internal long m_simulationStep = 0; // The current simulation step. |
99 | public long SimulationStep { get { return m_simulationStep; } } | 99 | public long SimulationStep { get { return m_simulationStep; } } |
100 | // A number to use for SimulationStep that is probably not any step value | ||
101 | // Used by the collision code (which remembers the step when a collision happens) to remember not any simulation step. | ||
102 | public static long NotASimulationStep = -1234; | ||
100 | 103 | ||
101 | internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate() | 104 | internal float LastTimeStep { get; private set; } // The simulation time from the last invocation of Simulate() |
102 | 105 | ||
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs index f424e7f..83732e2 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs | |||
@@ -51,7 +51,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
51 | m_virtScene.UnSubscribeToClientPrimEvents(client); | 51 | m_virtScene.UnSubscribeToClientPrimEvents(client); |
52 | m_virtScene.UnSubscribeToClientPrimRezEvents(client); | 52 | m_virtScene.UnSubscribeToClientPrimRezEvents(client); |
53 | m_virtScene.UnSubscribeToClientInventoryEvents(client); | 53 | m_virtScene.UnSubscribeToClientInventoryEvents(client); |
54 | ((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client); | 54 | if(m_virtScene.AttachmentsModule != null) |
55 | ((AttachmentsModule)m_virtScene.AttachmentsModule).UnsubscribeFromClientEvents(client); | ||
55 | //m_virtScene.UnSubscribeToClientTeleportEvents(client); | 56 | //m_virtScene.UnSubscribeToClientTeleportEvents(client); |
56 | m_virtScene.UnSubscribeToClientScriptEvents(client); | 57 | m_virtScene.UnSubscribeToClientScriptEvents(client); |
57 | 58 | ||
@@ -66,7 +67,8 @@ namespace OpenSim.Region.RegionCombinerModule | |||
66 | client.OnRezObject += LocalRezObject; | 67 | client.OnRezObject += LocalRezObject; |
67 | 68 | ||
68 | m_rootScene.SubscribeToClientInventoryEvents(client); | 69 | m_rootScene.SubscribeToClientInventoryEvents(client); |
69 | ((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client); | 70 | if (m_rootScene.AttachmentsModule != null) |
71 | ((AttachmentsModule)m_rootScene.AttachmentsModule).SubscribeToClientEvents(client); | ||
70 | //m_rootScene.SubscribeToClientTeleportEvents(client); | 72 | //m_rootScene.SubscribeToClientTeleportEvents(client); |
71 | m_rootScene.SubscribeToClientScriptEvents(client); | 73 | m_rootScene.SubscribeToClientScriptEvents(client); |
72 | 74 | ||
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index f28dd3e..8055886 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -1723,5 +1723,9 @@ MaxStringSpace = 0 | |||
1723 | ;; {MaxDistance} {} {Cut-off distance at which sounds will not be sent to users} {100.0} | 1723 | ;; {MaxDistance} {} {Cut-off distance at which sounds will not be sent to users} {100.0} |
1724 | MaxDistance = 100.0 | 1724 | MaxDistance = 100.0 |
1725 | 1725 | ||
1726 | [ServiceThrottle] | ||
1727 | ;; Default time interval (in ms) for the throttle service thread to wake up | ||
1728 | Interval = 5000 | ||
1729 | |||
1726 | [Modules] | 1730 | [Modules] |
1727 | Include-modules = "addon-modules/*/config/*.ini" | 1731 | Include-modules = "addon-modules/*/config/*.ini" |