diff options
Diffstat (limited to 'OpenSim')
171 files changed, 4798 insertions, 1447 deletions
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index 9fbc1b3..7d57de1 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | |||
@@ -561,7 +561,7 @@ namespace OpenSim.Groups | |||
561 | 561 | ||
562 | // so we have the list of urls to send the notice to | 562 | // so we have the list of urls to send the notice to |
563 | // this may take a long time... | 563 | // this may take a long time... |
564 | Watchdog.RunInThread(delegate | 564 | WorkManager.RunInThread(delegate |
565 | { | 565 | { |
566 | foreach (string u in urls) | 566 | foreach (string u in urls) |
567 | { | 567 | { |
@@ -572,7 +572,7 @@ namespace OpenSim.Groups | |||
572 | hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID)); | 572 | hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID)); |
573 | } | 573 | } |
574 | } | 574 | } |
575 | }, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID) , null); | 575 | }, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID)); |
576 | 576 | ||
577 | return true; | 577 | return true; |
578 | } | 578 | } |
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index 720640e..9fe00e0 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs | |||
@@ -30,6 +30,7 @@ using System.Collections; | |||
30 | using System.Collections.Specialized; | 30 | using System.Collections.Specialized; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Text; | ||
33 | using System.Web; | 34 | using System.Web; |
34 | using log4net; | 35 | using log4net; |
35 | using Nini.Config; | 36 | using Nini.Config; |
@@ -43,41 +44,37 @@ using Caps = OpenSim.Framework.Capabilities.Caps; | |||
43 | 44 | ||
44 | namespace OpenSim.Capabilities.Handlers | 45 | namespace OpenSim.Capabilities.Handlers |
45 | { | 46 | { |
46 | public class GetMeshHandler | 47 | public class GetMeshHandler : BaseStreamHandler |
47 | { | 48 | { |
48 | // private static readonly ILog m_log = | 49 | // private static readonly ILog m_log = |
49 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | 51 | ||
51 | private IAssetService m_assetService; | 52 | private IAssetService m_assetService; |
52 | 53 | ||
53 | public GetMeshHandler(IAssetService assService) | 54 | public GetMeshHandler(string path, IAssetService assService, string name, string description) |
55 | : base("GET", path, name, description) | ||
54 | { | 56 | { |
55 | m_assetService = assService; | 57 | m_assetService = assService; |
56 | } | 58 | } |
57 | 59 | ||
58 | public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) | 60 | protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) |
59 | { | 61 | { |
60 | Hashtable responsedata = new Hashtable(); | 62 | // Try to parse the texture ID from the request URL |
61 | responsedata["int_response_code"] = 400; //501; //410; //404; | 63 | NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); |
62 | responsedata["content_type"] = "text/plain"; | 64 | string meshStr = query.GetOne("mesh_id"); |
63 | responsedata["keepalive"] = false; | ||
64 | responsedata["str_response_string"] = "Request wasn't what was expected"; | ||
65 | 65 | ||
66 | string meshStr = string.Empty; | 66 | // m_log.DebugFormat("Fetching mesh {0}", meshStr); |
67 | |||
68 | if (request.ContainsKey("mesh_id")) | ||
69 | meshStr = request["mesh_id"].ToString(); | ||
70 | 67 | ||
71 | UUID meshID = UUID.Zero; | 68 | UUID meshID = UUID.Zero; |
72 | if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) | 69 | if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) |
73 | { | 70 | { |
74 | if (m_assetService == null) | 71 | if (m_assetService == null) |
75 | { | 72 | { |
76 | responsedata["int_response_code"] = 404; //501; //410; //404; | 73 | httpResponse.StatusCode = 404; |
77 | responsedata["content_type"] = "text/plain"; | 74 | httpResponse.ContentType = "text/plain"; |
78 | responsedata["keepalive"] = false; | 75 | byte[] data = Encoding.UTF8.GetBytes("The asset service is unavailable. So is your mesh."); |
79 | responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; | 76 | httpResponse.Body.Write(data, 0, data.Length); |
80 | return responsedata; | 77 | return null; |
81 | } | 78 | } |
82 | 79 | ||
83 | AssetBase mesh = m_assetService.Get(meshID.ToString()); | 80 | AssetBase mesh = m_assetService.Get(meshID.ToString()); |
@@ -86,31 +83,32 @@ namespace OpenSim.Capabilities.Handlers | |||
86 | { | 83 | { |
87 | if (mesh.Type == (SByte)AssetType.Mesh) | 84 | if (mesh.Type == (SByte)AssetType.Mesh) |
88 | { | 85 | { |
89 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | 86 | byte[] data = mesh.Data; |
90 | responsedata["content_type"] = "application/vnd.ll.mesh"; | 87 | httpResponse.Body.Write(data, 0, data.Length); |
91 | responsedata["int_response_code"] = 200; | 88 | httpResponse.ContentType = "application/vnd.ll.mesh"; |
89 | httpResponse.StatusCode = 200; | ||
92 | } | 90 | } |
93 | // Optionally add additional mesh types here | 91 | // Optionally add additional mesh types here |
94 | else | 92 | else |
95 | { | 93 | { |
96 | responsedata["int_response_code"] = 404; //501; //410; //404; | 94 | httpResponse.StatusCode = 404; |
97 | responsedata["content_type"] = "text/plain"; | 95 | httpResponse.ContentType = "text/plain"; |
98 | responsedata["keepalive"] = false; | 96 | byte[] data = Encoding.UTF8.GetBytes("Unfortunately, this asset isn't a mesh."); |
99 | responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; | 97 | httpResponse.Body.Write(data, 0, data.Length); |
100 | return responsedata; | 98 | httpResponse.KeepAlive = false; |
101 | } | 99 | } |
102 | } | 100 | } |
103 | else | 101 | else |
104 | { | 102 | { |
105 | responsedata["int_response_code"] = 404; //501; //410; //404; | 103 | httpResponse.StatusCode = 404; |
106 | responsedata["content_type"] = "text/plain"; | 104 | httpResponse.ContentType = "text/plain"; |
107 | responsedata["keepalive"] = false; | 105 | byte[] data = Encoding.UTF8.GetBytes("Your Mesh wasn't found. Sorry!"); |
108 | responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; | 106 | httpResponse.Body.Write(data, 0, data.Length); |
109 | return responsedata; | 107 | httpResponse.KeepAlive = false; |
110 | } | 108 | } |
111 | } | 109 | } |
112 | 110 | ||
113 | return responsedata; | 111 | return null; |
114 | } | 112 | } |
115 | } | 113 | } |
116 | } \ No newline at end of file | 114 | } \ No newline at end of file |
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs index 8a275f3..9c53862 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshServerConnector.cs | |||
@@ -65,15 +65,8 @@ namespace OpenSim.Capabilities.Handlers | |||
65 | if (m_AssetService == null) | 65 | if (m_AssetService == null) |
66 | throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); | 66 | throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); |
67 | 67 | ||
68 | GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); | 68 | server.AddStreamHandler( |
69 | IRequestHandler reqHandler | 69 | new GetMeshHandler("/CAPS/GetMesh/" /*+ UUID.Random() */, m_AssetService, "GetMesh", null)); |
70 | = new RestHTTPHandler( | ||
71 | "GET", | ||
72 | "/CAPS/" + UUID.Random(), | ||
73 | httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), | ||
74 | "GetMesh", | ||
75 | null); | ||
76 | server.AddStreamHandler(reqHandler); | ||
77 | } | 70 | } |
78 | } | 71 | } |
79 | } \ No newline at end of file | 72 | } \ No newline at end of file |
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs index 4f482f6..e5d9618 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Framework; | |||
37 | using OpenSim.Framework.Servers.HttpServer; | 37 | using OpenSim.Framework.Servers.HttpServer; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Capabilities.Handlers.GetTexture.Tests | 41 | namespace OpenSim.Capabilities.Handlers.GetTexture.Tests |
43 | { | 42 | { |
diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index d68078e..98e4465 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs | |||
@@ -54,6 +54,10 @@ namespace OpenSim.Framework | |||
54 | public int assetThrottle; | 54 | public int assetThrottle; |
55 | public int textureThrottle; | 55 | public int textureThrottle; |
56 | public int totalThrottle; | 56 | public int totalThrottle; |
57 | |||
58 | // Used by adaptive only | ||
59 | public int targetThrottle; | ||
60 | |||
57 | public int maxThrottle; | 61 | public int maxThrottle; |
58 | 62 | ||
59 | public Dictionary<string, int> SyncRequests = new Dictionary<string,int>(); | 63 | public Dictionary<string, int> SyncRequests = new Dictionary<string,int>(); |
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs index de6fe30..72018e4 100644 --- a/OpenSim/Framework/Communications/RestClient.cs +++ b/OpenSim/Framework/Communications/RestClient.cs | |||
@@ -483,7 +483,7 @@ namespace OpenSim.Framework.Communications | |||
483 | /// In case, we are invoked asynchroneously this object will keep track of the state | 483 | /// In case, we are invoked asynchroneously this object will keep track of the state |
484 | /// </summary> | 484 | /// </summary> |
485 | AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); | 485 | AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); |
486 | Util.FireAndForget(RequestHelper, ar); | 486 | Util.FireAndForget(RequestHelper, ar, "RestClient.BeginRequest"); |
487 | return ar; | 487 | return ar; |
488 | } | 488 | } |
489 | 489 | ||
diff --git a/OpenSim/Framework/Monitoring/JobEngine.cs b/OpenSim/Framework/Monitoring/JobEngine.cs new file mode 100644 index 0000000..5925867 --- /dev/null +++ b/OpenSim/Framework/Monitoring/JobEngine.cs | |||
@@ -0,0 +1,320 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Concurrent; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using log4net; | ||
33 | using OpenSim.Framework; | ||
34 | |||
35 | namespace OpenSim.Framework.Monitoring | ||
36 | { | ||
37 | public class Job | ||
38 | { | ||
39 | public string Name; | ||
40 | public WaitCallback Callback; | ||
41 | public object O; | ||
42 | |||
43 | public Job(string name, WaitCallback callback, object o) | ||
44 | { | ||
45 | Name = name; | ||
46 | Callback = callback; | ||
47 | O = o; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | public class JobEngine | ||
52 | { | ||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
54 | |||
55 | public int LogLevel { get; set; } | ||
56 | |||
57 | public bool IsRunning { get; private set; } | ||
58 | |||
59 | /// <summary> | ||
60 | /// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping. | ||
61 | /// </summary> | ||
62 | public int RequestProcessTimeoutOnStop { get; set; } | ||
63 | |||
64 | /// <summary> | ||
65 | /// Controls whether we need to warn in the log about exceeding the max queue size. | ||
66 | /// </summary> | ||
67 | /// <remarks> | ||
68 | /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in | ||
69 | /// order to avoid spamming the log with lots of warnings. | ||
70 | /// </remarks> | ||
71 | private bool m_warnOverMaxQueue = true; | ||
72 | |||
73 | private BlockingCollection<Job> m_requestQueue; | ||
74 | |||
75 | private CancellationTokenSource m_cancelSource = new CancellationTokenSource(); | ||
76 | |||
77 | private Stat m_requestsWaitingStat; | ||
78 | |||
79 | private Job m_currentJob; | ||
80 | |||
81 | /// <summary> | ||
82 | /// Used to signal that we are ready to complete stop. | ||
83 | /// </summary> | ||
84 | private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false); | ||
85 | |||
86 | public JobEngine() | ||
87 | { | ||
88 | RequestProcessTimeoutOnStop = 5000; | ||
89 | |||
90 | MainConsole.Instance.Commands.AddCommand( | ||
91 | "Debug", | ||
92 | false, | ||
93 | "debug jobengine", | ||
94 | "debug jobengine <start|stop|status|log>", | ||
95 | "Start, stop, get status or set logging level of the job engine.", | ||
96 | "If stopped then all outstanding jobs are processed immediately.", | ||
97 | HandleControlCommand); | ||
98 | } | ||
99 | |||
100 | public void Start() | ||
101 | { | ||
102 | lock (this) | ||
103 | { | ||
104 | if (IsRunning) | ||
105 | return; | ||
106 | |||
107 | IsRunning = true; | ||
108 | |||
109 | m_finishedProcessingAfterStop.Reset(); | ||
110 | |||
111 | m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000); | ||
112 | |||
113 | m_requestsWaitingStat = | ||
114 | new Stat( | ||
115 | "JobsWaiting", | ||
116 | "Number of jobs waiting for processing.", | ||
117 | "", | ||
118 | "", | ||
119 | "server", | ||
120 | "jobengine", | ||
121 | StatType.Pull, | ||
122 | MeasuresOfInterest.None, | ||
123 | stat => stat.Value = m_requestQueue.Count, | ||
124 | StatVerbosity.Debug); | ||
125 | |||
126 | StatsManager.RegisterStat(m_requestsWaitingStat); | ||
127 | |||
128 | WorkManager.StartThread( | ||
129 | ProcessRequests, | ||
130 | "JobEngineThread", | ||
131 | ThreadPriority.Normal, | ||
132 | false, | ||
133 | true, | ||
134 | null, | ||
135 | int.MaxValue); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | public void Stop() | ||
140 | { | ||
141 | lock (this) | ||
142 | { | ||
143 | try | ||
144 | { | ||
145 | if (!IsRunning) | ||
146 | return; | ||
147 | |||
148 | IsRunning = false; | ||
149 | |||
150 | int requestsLeft = m_requestQueue.Count; | ||
151 | |||
152 | if (requestsLeft <= 0) | ||
153 | { | ||
154 | m_cancelSource.Cancel(); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | m_log.InfoFormat("[JOB ENGINE]: Waiting to write {0} events after stop.", requestsLeft); | ||
159 | |||
160 | while (requestsLeft > 0) | ||
161 | { | ||
162 | if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop)) | ||
163 | { | ||
164 | // After timeout no events have been written | ||
165 | if (requestsLeft == m_requestQueue.Count) | ||
166 | { | ||
167 | m_log.WarnFormat( | ||
168 | "[JOB ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests", | ||
169 | RequestProcessTimeoutOnStop, requestsLeft); | ||
170 | |||
171 | break; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | requestsLeft = m_requestQueue.Count; | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | finally | ||
180 | { | ||
181 | m_cancelSource.Dispose(); | ||
182 | StatsManager.DeregisterStat(m_requestsWaitingStat); | ||
183 | m_requestsWaitingStat = null; | ||
184 | m_requestQueue = null; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | |||
189 | public bool QueueRequest(string name, WaitCallback req, object o) | ||
190 | { | ||
191 | if (LogLevel >= 1) | ||
192 | m_log.DebugFormat("[JOB ENGINE]: Queued job {0}", name); | ||
193 | |||
194 | if (m_requestQueue.Count < m_requestQueue.BoundedCapacity) | ||
195 | { | ||
196 | // m_log.DebugFormat( | ||
197 | // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}", | ||
198 | // categories, client.AgentID, m_udpServer.Scene.Name); | ||
199 | |||
200 | m_requestQueue.Add(new Job(name, req, o)); | ||
201 | |||
202 | if (!m_warnOverMaxQueue) | ||
203 | m_warnOverMaxQueue = true; | ||
204 | |||
205 | return true; | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | if (m_warnOverMaxQueue) | ||
210 | { | ||
211 | // m_log.WarnFormat( | ||
212 | // "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}", | ||
213 | // client.AgentID, m_udpServer.Scene.Name); | ||
214 | |||
215 | m_log.WarnFormat("[JOB ENGINE]: Request queue at maximum capacity, not recording job"); | ||
216 | |||
217 | m_warnOverMaxQueue = false; | ||
218 | } | ||
219 | |||
220 | return false; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | private void ProcessRequests() | ||
225 | { | ||
226 | try | ||
227 | { | ||
228 | while (IsRunning || m_requestQueue.Count > 0) | ||
229 | { | ||
230 | m_currentJob = m_requestQueue.Take(m_cancelSource.Token); | ||
231 | |||
232 | // QueueEmpty callback = req.Client.OnQueueEmpty; | ||
233 | // | ||
234 | // if (callback != null) | ||
235 | // { | ||
236 | // try | ||
237 | // { | ||
238 | // callback(req.Categories); | ||
239 | // } | ||
240 | // catch (Exception e) | ||
241 | // { | ||
242 | // m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e); | ||
243 | // } | ||
244 | // } | ||
245 | |||
246 | if (LogLevel >= 1) | ||
247 | m_log.DebugFormat("[JOB ENGINE]: Processing job {0}", m_currentJob.Name); | ||
248 | |||
249 | try | ||
250 | { | ||
251 | m_currentJob.Callback.Invoke(m_currentJob.O); | ||
252 | } | ||
253 | catch (Exception e) | ||
254 | { | ||
255 | m_log.Error( | ||
256 | string.Format( | ||
257 | "[JOB ENGINE]: Job {0} failed, continuing. Exception ", m_currentJob.Name), e); | ||
258 | } | ||
259 | |||
260 | if (LogLevel >= 1) | ||
261 | m_log.DebugFormat("[JOB ENGINE]: Processed job {0}", m_currentJob.Name); | ||
262 | |||
263 | m_currentJob = null; | ||
264 | } | ||
265 | } | ||
266 | catch (OperationCanceledException) | ||
267 | { | ||
268 | } | ||
269 | |||
270 | m_finishedProcessingAfterStop.Set(); | ||
271 | } | ||
272 | |||
273 | private void HandleControlCommand(string module, string[] args) | ||
274 | { | ||
275 | // if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
276 | // return; | ||
277 | |||
278 | if (args.Length < 3) | ||
279 | { | ||
280 | MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|log>"); | ||
281 | return; | ||
282 | } | ||
283 | |||
284 | string subCommand = args[2]; | ||
285 | |||
286 | if (subCommand == "stop") | ||
287 | { | ||
288 | Stop(); | ||
289 | MainConsole.Instance.OutputFormat("Stopped job engine."); | ||
290 | } | ||
291 | else if (subCommand == "start") | ||
292 | { | ||
293 | Start(); | ||
294 | MainConsole.Instance.OutputFormat("Started job engine."); | ||
295 | } | ||
296 | else if (subCommand == "status") | ||
297 | { | ||
298 | MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning); | ||
299 | MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none"); | ||
300 | MainConsole.Instance.OutputFormat( | ||
301 | "Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a"); | ||
302 | MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel); | ||
303 | } | ||
304 | else if (subCommand == "log") | ||
305 | { | ||
306 | // int logLevel; | ||
307 | int logLevel = int.Parse(args[3]); | ||
308 | // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel)) | ||
309 | // { | ||
310 | LogLevel = logLevel; | ||
311 | MainConsole.Instance.OutputFormat("Set debug log level to {0}", LogLevel); | ||
312 | // } | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand); | ||
317 | } | ||
318 | } | ||
319 | } | ||
320 | } | ||
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs index 0fcb195..a644fa5 100644 --- a/OpenSim/Framework/Monitoring/Watchdog.cs +++ b/OpenSim/Framework/Monitoring/Watchdog.cs | |||
@@ -38,6 +38,8 @@ namespace OpenSim.Framework.Monitoring | |||
38 | /// </summary> | 38 | /// </summary> |
39 | public static class Watchdog | 39 | public static class Watchdog |
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
42 | |||
41 | /// <summary>Timer interval in milliseconds for the watchdog timer</summary> | 43 | /// <summary>Timer interval in milliseconds for the watchdog timer</summary> |
42 | public const double WATCHDOG_INTERVAL_MS = 2500.0d; | 44 | public const double WATCHDOG_INTERVAL_MS = 2500.0d; |
43 | 45 | ||
@@ -141,7 +143,7 @@ namespace OpenSim.Framework.Monitoring | |||
141 | get { return m_enabled; } | 143 | get { return m_enabled; } |
142 | set | 144 | set |
143 | { | 145 | { |
144 | // m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value); | 146 | // m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value); |
145 | 147 | ||
146 | if (value == m_enabled) | 148 | if (value == m_enabled) |
147 | return; | 149 | return; |
@@ -157,9 +159,8 @@ namespace OpenSim.Framework.Monitoring | |||
157 | m_watchdogTimer.Enabled = m_enabled; | 159 | m_watchdogTimer.Enabled = m_enabled; |
158 | } | 160 | } |
159 | } | 161 | } |
160 | private static bool m_enabled; | ||
161 | 162 | ||
162 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 163 | private static bool m_enabled; |
163 | private static Dictionary<int, ThreadWatchdogInfo> m_threads; | 164 | private static Dictionary<int, ThreadWatchdogInfo> m_threads; |
164 | private static System.Timers.Timer m_watchdogTimer; | 165 | private static System.Timers.Timer m_watchdogTimer; |
165 | 166 | ||
@@ -180,94 +181,19 @@ namespace OpenSim.Framework.Monitoring | |||
180 | } | 181 | } |
181 | 182 | ||
182 | /// <summary> | 183 | /// <summary> |
183 | /// Start a new thread that is tracked by the watchdog timer. | 184 | /// Add a thread to the watchdog tracker. |
184 | /// </summary> | 185 | /// </summary> |
185 | /// <param name="start">The method that will be executed in a new thread</param> | 186 | /// <param name="info">Information about the thread.</info> |
186 | /// <param name="name">A name to give to the new thread</param> | 187 | /// <param name="info">Name of the thread.</info> |
187 | /// <param name="priority">Priority to run the thread at</param> | ||
188 | /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param> | ||
189 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> | ||
190 | /// <param name="log">If true then creation of thread is logged.</param> | 188 | /// <param name="log">If true then creation of thread is logged.</param> |
191 | /// <returns>The newly created Thread object</returns> | 189 | public static void AddThread(ThreadWatchdogInfo info, string name, bool log = true) |
192 | public static Thread StartThread( | ||
193 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true) | ||
194 | { | 190 | { |
195 | return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS, log); | ||
196 | } | ||
197 | |||
198 | /// <summary> | ||
199 | /// Start a new thread that is tracked by the watchdog | ||
200 | /// </summary> | ||
201 | /// <param name="start">The method that will be executed in a new thread</param> | ||
202 | /// <param name="name">A name to give to the new thread</param> | ||
203 | /// <param name="priority">Priority to run the thread at</param> | ||
204 | /// <param name="isBackground">True to run this thread as a background | ||
205 | /// thread, otherwise false</param> | ||
206 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> | ||
207 | /// <param name="alarmMethod"> | ||
208 | /// Alarm method to call if alarmIfTimeout is true and there is a timeout. | ||
209 | /// Normally, this will just return some useful debugging information. | ||
210 | /// </param> | ||
211 | /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> | ||
212 | /// <param name="log">If true then creation of thread is logged.</param> | ||
213 | /// <returns>The newly created Thread object</returns> | ||
214 | public static Thread StartThread( | ||
215 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, | ||
216 | bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true) | ||
217 | { | ||
218 | Thread thread = new Thread(start); | ||
219 | thread.Priority = priority; | ||
220 | thread.IsBackground = isBackground; | ||
221 | |||
222 | ThreadWatchdogInfo twi | ||
223 | = new ThreadWatchdogInfo(thread, timeout, name) | ||
224 | { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod }; | ||
225 | |||
226 | if (log) | 191 | if (log) |
227 | m_log.DebugFormat( | 192 | m_log.DebugFormat( |
228 | "[WATCHDOG]: Started tracking thread {0}, ID {1}", name, twi.Thread.ManagedThreadId); | 193 | "[WATCHDOG]: Started tracking thread {0}, ID {1}", name, info.Thread.ManagedThreadId); |
229 | 194 | ||
230 | lock (m_threads) | 195 | lock (m_threads) |
231 | m_threads.Add(twi.Thread.ManagedThreadId, twi); | 196 | m_threads.Add(info.Thread.ManagedThreadId, info); |
232 | |||
233 | thread.Start(); | ||
234 | thread.Name = name; | ||
235 | |||
236 | |||
237 | return thread; | ||
238 | } | ||
239 | |||
240 | /// <summary> | ||
241 | /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do | ||
242 | /// not propogate it. | ||
243 | /// </summary> | ||
244 | /// <param name="callback">Code for the thread to execute.</param> | ||
245 | /// <param name="name">Name of the thread</param> | ||
246 | /// <param name="obj">Object to pass to the thread.</param> | ||
247 | public static void RunInThread(WaitCallback callback, string name, object obj, bool log = false) | ||
248 | { | ||
249 | if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) | ||
250 | { | ||
251 | Culture.SetCurrentCulture(); | ||
252 | callback(obj); | ||
253 | return; | ||
254 | } | ||
255 | |||
256 | ThreadStart ts = new ThreadStart(delegate() | ||
257 | { | ||
258 | try | ||
259 | { | ||
260 | Culture.SetCurrentCulture(); | ||
261 | callback(obj); | ||
262 | Watchdog.RemoveThread(log:false); | ||
263 | } | ||
264 | catch (Exception e) | ||
265 | { | ||
266 | m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e); | ||
267 | } | ||
268 | }); | ||
269 | |||
270 | StartThread(ts, name, ThreadPriority.Normal, true, false, log:log); | ||
271 | } | 197 | } |
272 | 198 | ||
273 | /// <summary> | 199 | /// <summary> |
@@ -358,7 +284,7 @@ namespace OpenSim.Framework.Monitoring | |||
358 | } | 284 | } |
359 | catch { } | 285 | catch { } |
360 | } | 286 | } |
361 | 287 | ||
362 | /// <summary> | 288 | /// <summary> |
363 | /// Get currently watched threads for diagnostic purposes | 289 | /// Get currently watched threads for diagnostic purposes |
364 | /// </summary> | 290 | /// </summary> |
diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs new file mode 100644 index 0000000..9d0eefc --- /dev/null +++ b/OpenSim/Framework/Monitoring/WorkManager.cs | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using System.Threading; | ||
31 | using log4net; | ||
32 | |||
33 | namespace OpenSim.Framework.Monitoring | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// Manages various work items in the simulator. | ||
37 | /// </summary> | ||
38 | /// <remarks> | ||
39 | /// Currently, here work can be started | ||
40 | /// * As a long-running and monitored thread. | ||
41 | /// * In a thread that will never timeout but where the job is expected to eventually complete. | ||
42 | /// * In a threadpool thread that will timeout if it takes a very long time to complete (> 10 mins). | ||
43 | /// * As a job which will be run in a single-threaded job engine. Such jobs must not incorporate delays (sleeps, | ||
44 | /// network waits, etc.). | ||
45 | /// | ||
46 | /// This is an evolving approach to better manage the work that OpenSimulator is asked to do from a very diverse | ||
47 | /// range of sources (client actions, incoming network, outgoing network calls, etc.). | ||
48 | /// | ||
49 | /// Util.FireAndForget is still available to insert jobs in the threadpool, though this is equivalent to | ||
50 | /// WorkManager.RunInThreadPool(). | ||
51 | /// </remarks> | ||
52 | public static class WorkManager | ||
53 | { | ||
54 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
55 | |||
56 | public static JobEngine JobEngine { get; private set; } | ||
57 | |||
58 | static WorkManager() | ||
59 | { | ||
60 | JobEngine = new JobEngine(); | ||
61 | } | ||
62 | |||
63 | /// <summary> | ||
64 | /// Start a new long-lived thread. | ||
65 | /// </summary> | ||
66 | /// <param name="start">The method that will be executed in a new thread</param> | ||
67 | /// <param name="name">A name to give to the new thread</param> | ||
68 | /// <param name="priority">Priority to run the thread at</param> | ||
69 | /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param> | ||
70 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> | ||
71 | /// <param name="log">If true then creation of thread is logged.</param> | ||
72 | /// <returns>The newly created Thread object</returns> | ||
73 | public static Thread StartThread( | ||
74 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true) | ||
75 | { | ||
76 | return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS, log); | ||
77 | } | ||
78 | |||
79 | /// <summary> | ||
80 | /// Start a new thread that is tracked by the watchdog | ||
81 | /// </summary> | ||
82 | /// <param name="start">The method that will be executed in a new thread</param> | ||
83 | /// <param name="name">A name to give to the new thread</param> | ||
84 | /// <param name="priority">Priority to run the thread at</param> | ||
85 | /// <param name="isBackground">True to run this thread as a background | ||
86 | /// thread, otherwise false</param> | ||
87 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> | ||
88 | /// <param name="alarmMethod"> | ||
89 | /// Alarm method to call if alarmIfTimeout is true and there is a timeout. | ||
90 | /// Normally, this will just return some useful debugging information. | ||
91 | /// </param> | ||
92 | /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> | ||
93 | /// <param name="log">If true then creation of thread is logged.</param> | ||
94 | /// <returns>The newly created Thread object</returns> | ||
95 | public static Thread StartThread( | ||
96 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, | ||
97 | bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true) | ||
98 | { | ||
99 | Thread thread = new Thread(start); | ||
100 | thread.Priority = priority; | ||
101 | thread.IsBackground = isBackground; | ||
102 | |||
103 | Watchdog.ThreadWatchdogInfo twi | ||
104 | = new Watchdog.ThreadWatchdogInfo(thread, timeout, name) | ||
105 | { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod }; | ||
106 | |||
107 | Watchdog.AddThread(twi, name, log:log); | ||
108 | |||
109 | thread.Start(); | ||
110 | thread.Name = name; | ||
111 | |||
112 | return thread; | ||
113 | } | ||
114 | |||
115 | /// <summary> | ||
116 | /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do | ||
117 | /// not propogate it. | ||
118 | /// </summary> | ||
119 | /// <param name="callback">Code for the thread to execute.</param> | ||
120 | /// <param name="obj">Object to pass to the thread.</param> | ||
121 | /// <param name="name">Name of the thread</param> | ||
122 | public static void RunInThread(WaitCallback callback, object obj, string name, bool log = false) | ||
123 | { | ||
124 | if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) | ||
125 | { | ||
126 | Culture.SetCurrentCulture(); | ||
127 | callback(obj); | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | ThreadStart ts = new ThreadStart(delegate() | ||
132 | { | ||
133 | try | ||
134 | { | ||
135 | Culture.SetCurrentCulture(); | ||
136 | callback(obj); | ||
137 | Watchdog.RemoveThread(log:false); | ||
138 | } | ||
139 | catch (Exception e) | ||
140 | { | ||
141 | m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e); | ||
142 | } | ||
143 | }); | ||
144 | |||
145 | StartThread(ts, name, ThreadPriority.Normal, true, false, log:log); | ||
146 | } | ||
147 | |||
148 | /// <summary> | ||
149 | /// Run the callback via a threadpool thread. | ||
150 | /// </summary> | ||
151 | /// <remarks> | ||
152 | /// Such jobs may run after some delay but must always complete. | ||
153 | /// </remarks> | ||
154 | /// <param name="callback"></param> | ||
155 | /// <param name="obj"></param> | ||
156 | /// <param name="name">The name of the job. This is used in monitoring and debugging.</param> | ||
157 | public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name) | ||
158 | { | ||
159 | Util.FireAndForget(callback, obj, name); | ||
160 | } | ||
161 | |||
162 | /// <summary> | ||
163 | /// Run a job. | ||
164 | /// </summary> | ||
165 | /// <remarks> | ||
166 | /// This differs from direct scheduling (e.g. Util.FireAndForget) in that a job can be run in the job | ||
167 | /// engine if it is running, where all jobs are currently performed in sequence on a single thread. This is | ||
168 | /// to prevent observed overload and server freeze problems when there are hundreds of connections which all attempt to | ||
169 | /// perform work at once (e.g. in conference situations). With lower numbers of connections, the small | ||
170 | /// delay in performing jobs in sequence rather than concurrently has not been notiecable in testing, though a future more | ||
171 | /// sophisticated implementation could perform jobs concurrently when the server is under low load. | ||
172 | /// | ||
173 | /// However, be advised that some callers of this function rely on all jobs being performed in sequence if any | ||
174 | /// jobs are performed in sequence (i.e. if jobengine is active or not). Therefore, expanding the jobengine | ||
175 | /// beyond a single thread will require considerable thought. | ||
176 | /// | ||
177 | /// Also, any jobs submitted must be guaranteed to complete within a reasonable timeframe (e.g. they cannot | ||
178 | /// incorporate a network delay with a long timeout). At the moment, work that could suffer such issues | ||
179 | /// should still be run directly with RunInThread(), Util.FireAndForget(), etc. This is another area where | ||
180 | /// the job engine could be improved and so CPU utilization improved by better management of concurrency within | ||
181 | /// OpenSimulator. | ||
182 | /// </remarks> | ||
183 | /// <param name="jobType">General classification for the job (e.g. "RezAttachments").</param> | ||
184 | /// <param name="callback">Callback for job.</param> | ||
185 | /// <param name="obj">Object to pass to callback when run</param> | ||
186 | /// <param name="name">Specific name of job (e.g. "RezAttachments for Joe Bloggs"</param> | ||
187 | /// <param name="canRunInThisThread">If set to true then the job may be run in ths calling thread.</param> | ||
188 | /// <param name="mustNotTimeout">If the true then the job must never timeout.</param> | ||
189 | /// <param name="log">If set to true then extra logging is performed.</param> | ||
190 | public static void RunJob( | ||
191 | string jobType, WaitCallback callback, object obj, string name, | ||
192 | bool canRunInThisThread = false, bool mustNotTimeout = false, | ||
193 | bool log = false) | ||
194 | { | ||
195 | if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest) | ||
196 | { | ||
197 | Culture.SetCurrentCulture(); | ||
198 | callback(obj); | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | if (JobEngine.IsRunning) | ||
203 | JobEngine.QueueRequest(name, callback, obj); | ||
204 | else if (canRunInThisThread) | ||
205 | callback(obj); | ||
206 | else if (mustNotTimeout) | ||
207 | RunInThread(callback, obj, name, log); | ||
208 | else | ||
209 | Util.FireAndForget(callback, obj, name); | ||
210 | } | ||
211 | } | ||
212 | } \ No newline at end of file | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 4561d23..28bba70 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -120,7 +120,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
120 | for (uint i = 0; i < m_WorkerThreadCount; i++) | 120 | for (uint i = 0; i < m_WorkerThreadCount; i++) |
121 | { | 121 | { |
122 | m_workerThreads[i] | 122 | m_workerThreads[i] |
123 | = Watchdog.StartThread( | 123 | = WorkManager.StartThread( |
124 | PoolWorkerJob, | 124 | PoolWorkerJob, |
125 | string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port), | 125 | string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port), |
126 | ThreadPriority.Normal, | 126 | ThreadPriority.Normal, |
@@ -130,7 +130,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
130 | int.MaxValue); | 130 | int.MaxValue); |
131 | } | 131 | } |
132 | 132 | ||
133 | Watchdog.StartThread( | 133 | WorkManager.StartThread( |
134 | this.CheckLongPollThreads, | 134 | this.CheckLongPollThreads, |
135 | string.Format("LongPollServiceWatcherThread:{0}", m_server.Port), | 135 | string.Format("LongPollServiceWatcherThread:{0}", m_server.Port), |
136 | ThreadPriority.Normal, | 136 | ThreadPriority.Normal, |
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index fd56587..c22c119 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Diagnostics; | 30 | using System.Diagnostics; |
31 | using System.IO; | 31 | using System.IO; |
32 | using System.Linq; | ||
32 | using System.Reflection; | 33 | using System.Reflection; |
33 | using System.Text; | 34 | using System.Text; |
34 | using System.Text.RegularExpressions; | 35 | using System.Text.RegularExpressions; |
@@ -292,6 +293,18 @@ namespace OpenSim.Framework.Servers | |||
292 | HandleDebugThreadpoolLevel); | 293 | HandleDebugThreadpoolLevel); |
293 | 294 | ||
294 | m_console.Commands.AddCommand( | 295 | m_console.Commands.AddCommand( |
296 | "Debug", false, "show threadpool calls active", | ||
297 | "show threadpool calls active", | ||
298 | "Show details about threadpool calls that are still active (currently waiting or in progress)", | ||
299 | HandleShowThreadpoolCallsActive); | ||
300 | |||
301 | m_console.Commands.AddCommand( | ||
302 | "Debug", false, "show threadpool calls complete", | ||
303 | "show threadpool calls complete", | ||
304 | "Show details about threadpool calls that have been completed.", | ||
305 | HandleShowThreadpoolCallsComplete); | ||
306 | |||
307 | m_console.Commands.AddCommand( | ||
295 | "Debug", false, "force gc", | 308 | "Debug", false, "force gc", |
296 | "force gc", | 309 | "force gc", |
297 | "Manually invoke runtime garbage collection. For debugging purposes", | 310 | "Manually invoke runtime garbage collection. For debugging purposes", |
@@ -354,6 +367,57 @@ namespace OpenSim.Framework.Servers | |||
354 | Notice("serialosdreq is now {0}", setSerializeOsdRequests); | 367 | Notice("serialosdreq is now {0}", setSerializeOsdRequests); |
355 | } | 368 | } |
356 | 369 | ||
370 | private void HandleShowThreadpoolCallsActive(string module, string[] args) | ||
371 | { | ||
372 | List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsInProgress().ToList(); | ||
373 | calls.Sort((kvp1, kvp2) => kvp2.Value.CompareTo(kvp1.Value)); | ||
374 | int namedCalls = 0; | ||
375 | |||
376 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
377 | foreach (KeyValuePair<string, int> kvp in calls) | ||
378 | { | ||
379 | if (kvp.Value > 0) | ||
380 | { | ||
381 | cdl.AddRow(kvp.Key, kvp.Value); | ||
382 | namedCalls += kvp.Value; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | cdl.AddRow("TOTAL NAMED", namedCalls); | ||
387 | |||
388 | long allQueuedCalls = Util.TotalQueuedFireAndForgetCalls; | ||
389 | long allRunningCalls = Util.TotalRunningFireAndForgetCalls; | ||
390 | |||
391 | cdl.AddRow("TOTAL QUEUED", allQueuedCalls); | ||
392 | cdl.AddRow("TOTAL RUNNING", allRunningCalls); | ||
393 | cdl.AddRow("TOTAL ANONYMOUS", allQueuedCalls + allRunningCalls - namedCalls); | ||
394 | cdl.AddRow("TOTAL ALL", allQueuedCalls + allRunningCalls); | ||
395 | |||
396 | MainConsole.Instance.Output(cdl.ToString()); | ||
397 | } | ||
398 | |||
399 | private void HandleShowThreadpoolCallsComplete(string module, string[] args) | ||
400 | { | ||
401 | List<KeyValuePair<string, int>> calls = Util.GetFireAndForgetCallsMade().ToList(); | ||
402 | calls.Sort((kvp1, kvp2) => kvp2.Value.CompareTo(kvp1.Value)); | ||
403 | int namedCallsMade = 0; | ||
404 | |||
405 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
406 | foreach (KeyValuePair<string, int> kvp in calls) | ||
407 | { | ||
408 | cdl.AddRow(kvp.Key, kvp.Value); | ||
409 | namedCallsMade += kvp.Value; | ||
410 | } | ||
411 | |||
412 | cdl.AddRow("TOTAL NAMED", namedCallsMade); | ||
413 | |||
414 | long allCallsMade = Util.TotalFireAndForgetCallsMade; | ||
415 | cdl.AddRow("TOTAL ANONYMOUS", allCallsMade - namedCallsMade); | ||
416 | cdl.AddRow("TOTAL ALL", allCallsMade); | ||
417 | |||
418 | MainConsole.Instance.Output(cdl.ToString()); | ||
419 | } | ||
420 | |||
357 | private void HandleDebugThreadpoolStatus(string module, string[] args) | 421 | private void HandleDebugThreadpoolStatus(string module, string[] args) |
358 | { | 422 | { |
359 | int workerThreads, iocpThreads; | 423 | int workerThreads, iocpThreads; |
diff --git a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs index f33a045..d182a71 100644 --- a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs +++ b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs | |||
@@ -15,7 +15,7 @@ namespace OpenSim.Framework.ServiceAuth | |||
15 | private string m_Username, m_Password; | 15 | private string m_Username, m_Password; |
16 | private string m_CredentialsB64; | 16 | private string m_CredentialsB64; |
17 | 17 | ||
18 | private string remove_me; | 18 | // private string remove_me; |
19 | 19 | ||
20 | public string Credentials | 20 | public string Credentials |
21 | { | 21 | { |
@@ -24,7 +24,7 @@ namespace OpenSim.Framework.ServiceAuth | |||
24 | 24 | ||
25 | public BasicHttpAuthentication(IConfigSource config, string section) | 25 | public BasicHttpAuthentication(IConfigSource config, string section) |
26 | { | 26 | { |
27 | remove_me = section; | 27 | // remove_me = section; |
28 | m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty); | 28 | m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty); |
29 | m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty); | 29 | m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty); |
30 | string str = m_Username + ":" + m_Password; | 30 | string str = m_Username + ":" + m_Password; |
diff --git a/OpenSim/Framework/Tests/AnimationTests.cs b/OpenSim/Framework/Tests/AnimationTests.cs index f3be81b..d8f17d0 100644 --- a/OpenSim/Framework/Tests/AnimationTests.cs +++ b/OpenSim/Framework/Tests/AnimationTests.cs | |||
@@ -32,7 +32,6 @@ using OpenMetaverse; | |||
32 | using OpenMetaverse.StructuredData; | 32 | using OpenMetaverse.StructuredData; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Tests.Common; | 34 | using OpenSim.Tests.Common; |
35 | using OpenSim.Tests.Common.Mock; | ||
36 | using Animation = OpenSim.Framework.Animation; | 35 | using Animation = OpenSim.Framework.Animation; |
37 | 36 | ||
38 | namespace OpenSim.Framework.Tests | 37 | namespace OpenSim.Framework.Tests |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index fefa050..97c958a 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -1928,11 +1928,6 @@ namespace OpenSim.Framework | |||
1928 | } | 1928 | } |
1929 | } | 1929 | } |
1930 | 1930 | ||
1931 | public static void FireAndForget(System.Threading.WaitCallback callback) | ||
1932 | { | ||
1933 | FireAndForget(callback, null, null); | ||
1934 | } | ||
1935 | |||
1936 | public static void InitThreadPool(int minThreads, int maxThreads) | 1931 | public static void InitThreadPool(int minThreads, int maxThreads) |
1937 | { | 1932 | { |
1938 | if (maxThreads < 2) | 1933 | if (maxThreads < 2) |
@@ -1977,8 +1972,7 @@ namespace OpenSim.Framework | |||
1977 | throw new NotImplementedException(); | 1972 | throw new NotImplementedException(); |
1978 | } | 1973 | } |
1979 | } | 1974 | } |
1980 | 1975 | ||
1981 | |||
1982 | /// <summary> | 1976 | /// <summary> |
1983 | /// Additional information about threads in the main thread pool. Used to time how long the | 1977 | /// Additional information about threads in the main thread pool. Used to time how long the |
1984 | /// thread has been running, and abort it if it has timed-out. | 1978 | /// thread has been running, and abort it if it has timed-out. |
@@ -2052,12 +2046,15 @@ namespace OpenSim.Framework | |||
2052 | } | 2046 | } |
2053 | } | 2047 | } |
2054 | 2048 | ||
2055 | |||
2056 | private static long nextThreadFuncNum = 0; | 2049 | private static long nextThreadFuncNum = 0; |
2057 | private static long numQueuedThreadFuncs = 0; | 2050 | private static long numQueuedThreadFuncs = 0; |
2058 | private static long numRunningThreadFuncs = 0; | 2051 | private static long numRunningThreadFuncs = 0; |
2052 | private static long numTotalThreadFuncsCalled = 0; | ||
2059 | private static Int32 threadFuncOverloadMode = 0; | 2053 | private static Int32 threadFuncOverloadMode = 0; |
2060 | 2054 | ||
2055 | public static long TotalQueuedFireAndForgetCalls { get { return numQueuedThreadFuncs; } } | ||
2056 | public static long TotalRunningFireAndForgetCalls { get { return numRunningThreadFuncs; } } | ||
2057 | |||
2061 | // Maps (ThreadFunc number -> Thread) | 2058 | // Maps (ThreadFunc number -> Thread) |
2062 | private static ConcurrentDictionary<long, ThreadInfo> activeThreads = new ConcurrentDictionary<long, ThreadInfo>(); | 2059 | private static ConcurrentDictionary<long, ThreadInfo> activeThreads = new ConcurrentDictionary<long, ThreadInfo>(); |
2063 | 2060 | ||
@@ -2086,14 +2083,49 @@ namespace OpenSim.Framework | |||
2086 | } | 2083 | } |
2087 | } | 2084 | } |
2088 | 2085 | ||
2086 | public static long TotalFireAndForgetCallsMade { get { return numTotalThreadFuncsCalled; } } | ||
2087 | |||
2088 | public static Dictionary<string, int> GetFireAndForgetCallsMade() | ||
2089 | { | ||
2090 | return new Dictionary<string, int>(m_fireAndForgetCallsMade); | ||
2091 | } | ||
2092 | |||
2093 | private static Dictionary<string, int> m_fireAndForgetCallsMade = new Dictionary<string, int>(); | ||
2094 | |||
2095 | public static Dictionary<string, int> GetFireAndForgetCallsInProgress() | ||
2096 | { | ||
2097 | return new Dictionary<string, int>(m_fireAndForgetCallsInProgress); | ||
2098 | } | ||
2099 | |||
2100 | private static Dictionary<string, int> m_fireAndForgetCallsInProgress = new Dictionary<string, int>(); | ||
2101 | |||
2102 | public static void FireAndForget(System.Threading.WaitCallback callback) | ||
2103 | { | ||
2104 | FireAndForget(callback, null, null); | ||
2105 | } | ||
2089 | 2106 | ||
2090 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj) | 2107 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj) |
2091 | { | 2108 | { |
2092 | FireAndForget(callback, obj, null); | 2109 | FireAndForget(callback, obj, null); |
2093 | } | 2110 | } |
2094 | 2111 | ||
2095 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context) | 2112 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context) |
2096 | { | 2113 | { |
2114 | Interlocked.Increment(ref numTotalThreadFuncsCalled); | ||
2115 | |||
2116 | if (context != null) | ||
2117 | { | ||
2118 | if (!m_fireAndForgetCallsMade.ContainsKey(context)) | ||
2119 | m_fireAndForgetCallsMade[context] = 1; | ||
2120 | else | ||
2121 | m_fireAndForgetCallsMade[context]++; | ||
2122 | |||
2123 | if (!m_fireAndForgetCallsInProgress.ContainsKey(context)) | ||
2124 | m_fireAndForgetCallsInProgress[context] = 1; | ||
2125 | else | ||
2126 | m_fireAndForgetCallsInProgress[context]++; | ||
2127 | } | ||
2128 | |||
2097 | WaitCallback realCallback; | 2129 | WaitCallback realCallback; |
2098 | 2130 | ||
2099 | bool loggingEnabled = LogThreadPool > 0; | 2131 | bool loggingEnabled = LogThreadPool > 0; |
@@ -2104,7 +2136,15 @@ namespace OpenSim.Framework | |||
2104 | if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) | 2136 | if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) |
2105 | { | 2137 | { |
2106 | // If we're running regression tests, then we want any exceptions to rise up to the test code. | 2138 | // If we're running regression tests, then we want any exceptions to rise up to the test code. |
2107 | realCallback = o => { Culture.SetCurrentCulture(); callback(o); }; | 2139 | realCallback = |
2140 | o => | ||
2141 | { | ||
2142 | Culture.SetCurrentCulture(); | ||
2143 | callback(o); | ||
2144 | |||
2145 | if (context != null) | ||
2146 | m_fireAndForgetCallsInProgress[context]--; | ||
2147 | }; | ||
2108 | } | 2148 | } |
2109 | else | 2149 | else |
2110 | { | 2150 | { |
@@ -2143,6 +2183,9 @@ namespace OpenSim.Framework | |||
2143 | activeThreads.TryRemove(threadFuncNum, out dummy); | 2183 | activeThreads.TryRemove(threadFuncNum, out dummy); |
2144 | if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread) | 2184 | if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread) |
2145 | m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed())); | 2185 | m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed())); |
2186 | |||
2187 | if (context != null) | ||
2188 | m_fireAndForgetCallsInProgress[context]--; | ||
2146 | } | 2189 | } |
2147 | }; | 2190 | }; |
2148 | } | 2191 | } |
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index ab606a3..3be411a 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs | |||
@@ -337,6 +337,10 @@ namespace OpenSim | |||
337 | { | 337 | { |
338 | // Called from base.StartUp() | 338 | // Called from base.StartUp() |
339 | 339 | ||
340 | IConfig startupConfig = Config.Configs["Startup"]; | ||
341 | if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true)) | ||
342 | WorkManager.JobEngine.Start(); | ||
343 | |||
340 | m_httpServerPort = m_networkServersInfo.HttpListenerPort; | 344 | m_httpServerPort = m_networkServersInfo.HttpListenerPort; |
341 | SceneManager.OnRestartSim += HandleRestartRegion; | 345 | SceneManager.OnRestartSim += HandleRestartRegion; |
342 | 346 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index fb24f58..16a902d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework; | |||
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.OptionalModules.World.NPC; | 44 | using OpenSim.Region.OptionalModules.World.NPC; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.ClientStack.Linden.Tests | 47 | namespace OpenSim.Region.ClientStack.Linden.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 8e1f63a..4aecc99 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs | |||
@@ -110,32 +110,29 @@ namespace OpenSim.Region.ClientStack.Linden | |||
110 | 110 | ||
111 | #endregion | 111 | #endregion |
112 | 112 | ||
113 | |||
114 | public void RegisterCaps(UUID agentID, Caps caps) | 113 | public void RegisterCaps(UUID agentID, Caps caps) |
115 | { | 114 | { |
116 | // UUID capID = UUID.Random(); | ||
117 | 115 | ||
118 | //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); | 116 | //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); |
119 | if (m_URL == "localhost") | 117 | if (m_URL == "localhost") |
120 | { | 118 | { |
121 | // m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); | 119 | // m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); |
122 | GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); | 120 | |
123 | IRequestHandler reqHandler | 121 | UUID capID = UUID.Random(); |
124 | = new RestHTTPHandler( | 122 | |
125 | "GET", | 123 | caps.RegisterHandler( |
126 | "/CAPS/" + UUID.Random(), | 124 | "GetMesh", |
127 | httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), | 125 | new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString())); |
128 | "GetMesh", | ||
129 | agentID.ToString()); | ||
130 | |||
131 | caps.RegisterHandler("GetMesh", reqHandler); | ||
132 | } | 126 | } |
133 | else | 127 | else |
134 | { | 128 | { |
135 | // m_log.DebugFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); | 129 | // m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); |
136 | caps.RegisterHandler("GetMesh", m_URL); | 130 | IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>(); |
131 | if (handler != null) | ||
132 | handler.RegisterExternalUserCapsHandler(agentID, caps, "GetMesh", m_URL); | ||
133 | else | ||
134 | caps.RegisterHandler("GetMesh", m_URL); | ||
137 | } | 135 | } |
138 | } | 136 | } |
139 | |||
140 | } | 137 | } |
141 | } | 138 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index ec45c81..d4bdef6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs | |||
@@ -85,16 +85,21 @@ namespace OpenSim.Region.ClientStack.Linden | |||
85 | { | 85 | { |
86 | // These are normaly set in their respective modules | 86 | // These are normaly set in their respective modules |
87 | m_SearchURL = config.GetString("SearchServerURI", m_SearchURL); | 87 | m_SearchURL = config.GetString("SearchServerURI", m_SearchURL); |
88 | |||
88 | m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL); | 89 | m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL); |
90 | |||
89 | if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config | 91 | if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config |
90 | m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL); | 92 | m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL); |
93 | |||
91 | m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); | 94 | m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); |
92 | m_GridURL = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI", | 95 | |
93 | new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty); | 96 | m_GridURL = Util.GetConfigVarFromSections<string>( |
97 | source, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty); | ||
98 | |||
94 | m_GridName = config.GetString("GridName", string.Empty); | 99 | m_GridName = config.GetString("GridName", string.Empty); |
95 | if (m_GridName == string.Empty) | 100 | if (m_GridName == string.Empty) |
96 | m_GridName = Util.GetConfigVarFromSections<string>(source, "gridname", | 101 | m_GridName = Util.GetConfigVarFromSections<string>( |
97 | new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty); | 102 | source, "gridname", new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty); |
98 | } | 103 | } |
99 | 104 | ||
100 | AddDefaultFeatures(); | 105 | AddDefaultFeatures(); |
@@ -148,13 +153,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
148 | m_features["MeshUploadEnabled"] = true; | 153 | m_features["MeshUploadEnabled"] = true; |
149 | m_features["MeshXferEnabled"] = true; | 154 | m_features["MeshXferEnabled"] = true; |
150 | m_features["PhysicsMaterialsEnabled"] = true; | 155 | m_features["PhysicsMaterialsEnabled"] = true; |
151 | 156 | ||
152 | OSDMap typesMap = new OSDMap(); | 157 | OSDMap typesMap = new OSDMap(); |
153 | typesMap["convex"] = true; | 158 | typesMap["convex"] = true; |
154 | typesMap["none"] = true; | 159 | typesMap["none"] = true; |
155 | typesMap["prim"] = true; | 160 | typesMap["prim"] = true; |
156 | m_features["PhysicsShapeTypes"] = typesMap; | 161 | m_features["PhysicsShapeTypes"] = typesMap; |
157 | 162 | ||
158 | // Extra information for viewers that want to use it | 163 | // Extra information for viewers that want to use it |
159 | // TODO: Take these out of here into their respective modules, like map-server-url | 164 | // TODO: Take these out of here into their respective modules, like map-server-url |
160 | OSDMap extrasMap; | 165 | OSDMap extrasMap; |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs index ee1ea1a..39209ec 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs | |||
@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.Framework; | |||
47 | using OpenSim.Region.Framework.Scenes; | 47 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Services.Interfaces; | 48 | using OpenSim.Services.Interfaces; |
49 | using OpenSim.Tests.Common; | 49 | using OpenSim.Tests.Common; |
50 | using OpenSim.Tests.Common.Mock; | ||
51 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; | 50 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; |
52 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | 51 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; |
53 | 52 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 87192a0..84ca4bb 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -207,7 +207,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
207 | 207 | ||
208 | for (uint i = 0; i < 2; i++) | 208 | for (uint i = 0; i < 2; i++) |
209 | { | 209 | { |
210 | m_workerThreads[i] = Watchdog.StartThread(DoInventoryRequests, | 210 | m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, |
211 | String.Format("InventoryWorkerThread{0}", i), | 211 | String.Format("InventoryWorkerThread{0}", i), |
212 | ThreadPriority.Normal, | 212 | ThreadPriority.Normal, |
213 | false, | 213 | false, |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs new file mode 100644 index 0000000..6f40b24 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketAsyncHandlingEngine.cs | |||
@@ -0,0 +1,328 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Concurrent; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using log4net; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Monitoring; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | |||
37 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
38 | { | ||
39 | public class Job | ||
40 | { | ||
41 | public string Name; | ||
42 | public WaitCallback Callback; | ||
43 | public object O; | ||
44 | |||
45 | public Job(string name, WaitCallback callback, object o) | ||
46 | { | ||
47 | Name = name; | ||
48 | Callback = callback; | ||
49 | O = o; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | // TODO: These kinds of classes MUST be generalized with JobEngine, etc. | ||
54 | public class IncomingPacketAsyncHandlingEngine | ||
55 | { | ||
56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
57 | |||
58 | public int LogLevel { get; set; } | ||
59 | |||
60 | public bool IsRunning { get; private set; } | ||
61 | |||
62 | /// <summary> | ||
63 | /// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping. | ||
64 | /// </summary> | ||
65 | public int RequestProcessTimeoutOnStop { get; set; } | ||
66 | |||
67 | /// <summary> | ||
68 | /// Controls whether we need to warn in the log about exceeding the max queue size. | ||
69 | /// </summary> | ||
70 | /// <remarks> | ||
71 | /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in | ||
72 | /// order to avoid spamming the log with lots of warnings. | ||
73 | /// </remarks> | ||
74 | private bool m_warnOverMaxQueue = true; | ||
75 | |||
76 | private BlockingCollection<Job> m_requestQueue; | ||
77 | |||
78 | private CancellationTokenSource m_cancelSource = new CancellationTokenSource(); | ||
79 | |||
80 | private LLUDPServer m_udpServer; | ||
81 | |||
82 | private Stat m_requestsWaitingStat; | ||
83 | |||
84 | private Job m_currentJob; | ||
85 | |||
86 | /// <summary> | ||
87 | /// Used to signal that we are ready to complete stop. | ||
88 | /// </summary> | ||
89 | private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false); | ||
90 | |||
91 | public IncomingPacketAsyncHandlingEngine(LLUDPServer server) | ||
92 | { | ||
93 | //LogLevel = 1; | ||
94 | m_udpServer = server; | ||
95 | RequestProcessTimeoutOnStop = 5000; | ||
96 | |||
97 | // MainConsole.Instance.Commands.AddCommand( | ||
98 | // "Debug", | ||
99 | // false, | ||
100 | // "debug jobengine", | ||
101 | // "debug jobengine <start|stop|status>", | ||
102 | // "Start, stop or get status of the job engine.", | ||
103 | // "If stopped then all jobs are processed immediately.", | ||
104 | // HandleControlCommand); | ||
105 | } | ||
106 | |||
107 | public void Start() | ||
108 | { | ||
109 | lock (this) | ||
110 | { | ||
111 | if (IsRunning) | ||
112 | return; | ||
113 | |||
114 | IsRunning = true; | ||
115 | |||
116 | m_finishedProcessingAfterStop.Reset(); | ||
117 | |||
118 | m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000); | ||
119 | |||
120 | m_requestsWaitingStat = | ||
121 | new Stat( | ||
122 | "IncomingPacketAsyncRequestsWaiting", | ||
123 | "Number of incoming packets waiting for async processing in engine.", | ||
124 | "", | ||
125 | "", | ||
126 | "clientstack", | ||
127 | m_udpServer.Scene.Name, | ||
128 | StatType.Pull, | ||
129 | MeasuresOfInterest.None, | ||
130 | stat => stat.Value = m_requestQueue.Count, | ||
131 | StatVerbosity.Debug); | ||
132 | |||
133 | StatsManager.RegisterStat(m_requestsWaitingStat); | ||
134 | |||
135 | WorkManager.StartThread( | ||
136 | ProcessRequests, | ||
137 | string.Format("Incoming Packet Async Handling Engine Thread ({0})", m_udpServer.Scene.Name), | ||
138 | ThreadPriority.Normal, | ||
139 | false, | ||
140 | true, | ||
141 | null, | ||
142 | int.MaxValue); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | public void Stop() | ||
147 | { | ||
148 | lock (this) | ||
149 | { | ||
150 | try | ||
151 | { | ||
152 | if (!IsRunning) | ||
153 | return; | ||
154 | |||
155 | IsRunning = false; | ||
156 | |||
157 | int requestsLeft = m_requestQueue.Count; | ||
158 | |||
159 | if (requestsLeft <= 0) | ||
160 | { | ||
161 | m_cancelSource.Cancel(); | ||
162 | } | ||
163 | else | ||
164 | { | ||
165 | m_log.InfoFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Waiting to write {0} events after stop.", requestsLeft); | ||
166 | |||
167 | while (requestsLeft > 0) | ||
168 | { | ||
169 | if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop)) | ||
170 | { | ||
171 | // After timeout no events have been written | ||
172 | if (requestsLeft == m_requestQueue.Count) | ||
173 | { | ||
174 | m_log.WarnFormat( | ||
175 | "[INCOMING PACKET ASYNC HANDLING ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests", | ||
176 | RequestProcessTimeoutOnStop, requestsLeft); | ||
177 | |||
178 | break; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | requestsLeft = m_requestQueue.Count; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | finally | ||
187 | { | ||
188 | m_cancelSource.Dispose(); | ||
189 | StatsManager.DeregisterStat(m_requestsWaitingStat); | ||
190 | m_requestsWaitingStat = null; | ||
191 | m_requestQueue = null; | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | public bool QueueRequest(string name, WaitCallback req, object o) | ||
197 | { | ||
198 | if (LogLevel >= 1) | ||
199 | m_log.DebugFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Queued job {0}", name); | ||
200 | |||
201 | if (m_requestQueue.Count < m_requestQueue.BoundedCapacity) | ||
202 | { | ||
203 | // m_log.DebugFormat( | ||
204 | // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}", | ||
205 | // categories, client.AgentID, m_udpServer.Scene.Name); | ||
206 | |||
207 | m_requestQueue.Add(new Job(name, req, o)); | ||
208 | |||
209 | if (!m_warnOverMaxQueue) | ||
210 | m_warnOverMaxQueue = true; | ||
211 | |||
212 | return true; | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | if (m_warnOverMaxQueue) | ||
217 | { | ||
218 | // m_log.WarnFormat( | ||
219 | // "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}", | ||
220 | // client.AgentID, m_udpServer.Scene.Name); | ||
221 | |||
222 | m_log.WarnFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Request queue at maximum capacity, not recording job"); | ||
223 | |||
224 | m_warnOverMaxQueue = false; | ||
225 | } | ||
226 | |||
227 | return false; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | private void ProcessRequests() | ||
232 | { | ||
233 | try | ||
234 | { | ||
235 | while (IsRunning || m_requestQueue.Count > 0) | ||
236 | { | ||
237 | m_currentJob = m_requestQueue.Take(m_cancelSource.Token); | ||
238 | |||
239 | // QueueEmpty callback = req.Client.OnQueueEmpty; | ||
240 | // | ||
241 | // if (callback != null) | ||
242 | // { | ||
243 | // try | ||
244 | // { | ||
245 | // callback(req.Categories); | ||
246 | // } | ||
247 | // catch (Exception e) | ||
248 | // { | ||
249 | // m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e); | ||
250 | // } | ||
251 | // } | ||
252 | |||
253 | if (LogLevel >= 1) | ||
254 | m_log.DebugFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Processing job {0}", m_currentJob.Name); | ||
255 | |||
256 | try | ||
257 | { | ||
258 | m_currentJob.Callback.Invoke(m_currentJob.O); | ||
259 | } | ||
260 | catch (Exception e) | ||
261 | { | ||
262 | m_log.Error( | ||
263 | string.Format( | ||
264 | "[INCOMING PACKET ASYNC HANDLING ENGINE]: Job {0} failed, continuing. Exception ", m_currentJob.Name), e); | ||
265 | } | ||
266 | |||
267 | if (LogLevel >= 1) | ||
268 | m_log.DebugFormat("[INCOMING PACKET ASYNC HANDLING ENGINE]: Processed job {0}", m_currentJob.Name); | ||
269 | |||
270 | m_currentJob = null; | ||
271 | } | ||
272 | } | ||
273 | catch (OperationCanceledException) | ||
274 | { | ||
275 | } | ||
276 | |||
277 | m_finishedProcessingAfterStop.Set(); | ||
278 | } | ||
279 | |||
280 | // private void HandleControlCommand(string module, string[] args) | ||
281 | // { | ||
282 | // // if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
283 | // // return; | ||
284 | // | ||
285 | // if (args.Length < 3) | ||
286 | // { | ||
287 | // MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|loglevel>"); | ||
288 | // return; | ||
289 | // } | ||
290 | // | ||
291 | // string subCommand = args[2]; | ||
292 | // | ||
293 | // if (subCommand == "stop") | ||
294 | // { | ||
295 | // Stop(); | ||
296 | // MainConsole.Instance.OutputFormat("Stopped job engine."); | ||
297 | // } | ||
298 | // else if (subCommand == "start") | ||
299 | // { | ||
300 | // Start(); | ||
301 | // MainConsole.Instance.OutputFormat("Started job engine."); | ||
302 | // } | ||
303 | // else if (subCommand == "status") | ||
304 | // { | ||
305 | // MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning); | ||
306 | // MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none"); | ||
307 | // MainConsole.Instance.OutputFormat( | ||
308 | // "Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a"); | ||
309 | // MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel); | ||
310 | // } | ||
311 | // | ||
312 | // else if (subCommand == "loglevel") | ||
313 | // { | ||
314 | // // int logLevel; | ||
315 | // int logLevel = int.Parse(args[3]); | ||
316 | // // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel)) | ||
317 | // // { | ||
318 | // LogLevel = logLevel; | ||
319 | // MainConsole.Instance.OutputFormat("Set log level to {0}", LogLevel); | ||
320 | // // } | ||
321 | // } | ||
322 | // else | ||
323 | // { | ||
324 | // MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand); | ||
325 | // } | ||
326 | // } | ||
327 | } | ||
328 | } | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c839c05..85f9d68 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -648,12 +648,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
648 | /// <returns>true if the handler was added. This is currently always the case.</returns> | 648 | /// <returns>true if the handler was added. This is currently always the case.</returns> |
649 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) | 649 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) |
650 | { | 650 | { |
651 | return AddLocalPacketHandler(packetType, handler, doAsync, false); | ||
652 | } | ||
653 | |||
654 | /// <summary> | ||
655 | /// Add a handler for the given packet type. | ||
656 | /// </summary> | ||
657 | /// <param name="packetType"></param> | ||
658 | /// <param name="handler"></param> | ||
659 | /// <param name="doAsync"> | ||
660 | /// If true, when the packet is received handle it on a different thread. Whether this is given direct to | ||
661 | /// a threadpool thread or placed in a queue depends on the inEngine parameter. | ||
662 | /// </param> | ||
663 | /// <param name="inEngine"> | ||
664 | /// If async is false then this parameter is ignored. | ||
665 | /// If async is true and inEngine is false, then the packet is sent directly to a | ||
666 | /// threadpool thread. | ||
667 | /// If async is true and inEngine is true, then the packet is sent to the IncomingPacketAsyncHandlingEngine. | ||
668 | /// This may result in slower handling but reduces the risk of overloading the simulator when there are many | ||
669 | /// simultaneous async requests. | ||
670 | /// </param> | ||
671 | /// <returns>true if the handler was added. This is currently always the case.</returns> | ||
672 | public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync, bool inEngine) | ||
673 | { | ||
651 | bool result = false; | 674 | bool result = false; |
652 | lock (m_packetHandlers) | 675 | lock (m_packetHandlers) |
653 | { | 676 | { |
654 | if (!m_packetHandlers.ContainsKey(packetType)) | 677 | if (!m_packetHandlers.ContainsKey(packetType)) |
655 | { | 678 | { |
656 | m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync }); | 679 | m_packetHandlers.Add( |
680 | packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine }); | ||
657 | result = true; | 681 | result = true; |
658 | } | 682 | } |
659 | } | 683 | } |
@@ -688,21 +712,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
688 | PacketProcessor pprocessor; | 712 | PacketProcessor pprocessor; |
689 | if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) | 713 | if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) |
690 | { | 714 | { |
715 | ClientInfo cinfo = UDPClient.GetClientInfo(); | ||
716 | |||
691 | //there is a local handler for this packet type | 717 | //there is a local handler for this packet type |
692 | if (pprocessor.Async) | 718 | if (pprocessor.Async) |
693 | { | 719 | { |
694 | ClientInfo cinfo = UDPClient.GetClientInfo(); | ||
695 | if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString())) | 720 | if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString())) |
696 | cinfo.AsyncRequests[packet.Type.ToString()] = 0; | 721 | cinfo.AsyncRequests[packet.Type.ToString()] = 0; |
697 | cinfo.AsyncRequests[packet.Type.ToString()]++; | 722 | cinfo.AsyncRequests[packet.Type.ToString()]++; |
698 | 723 | ||
699 | object obj = new AsyncPacketProcess(this, pprocessor.method, packet); | 724 | object obj = new AsyncPacketProcess(this, pprocessor.method, packet); |
700 | Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString()); | 725 | |
726 | if (pprocessor.InEngine) | ||
727 | m_udpServer.IpahEngine.QueueRequest( | ||
728 | packet.Type.ToString(), | ||
729 | ProcessSpecificPacketAsync, | ||
730 | obj); | ||
731 | else | ||
732 | Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString()); | ||
733 | |||
701 | result = true; | 734 | result = true; |
702 | } | 735 | } |
703 | else | 736 | else |
704 | { | 737 | { |
705 | ClientInfo cinfo = UDPClient.GetClientInfo(); | ||
706 | if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString())) | 738 | if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString())) |
707 | cinfo.SyncRequests[packet.Type.ToString()] = 0; | 739 | cinfo.SyncRequests[packet.Type.ToString()] = 0; |
708 | cinfo.SyncRequests[packet.Type.ToString()]++; | 740 | cinfo.SyncRequests[packet.Type.ToString()]++; |
@@ -1161,7 +1193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1161 | /// <param name="map">heightmap</param> | 1193 | /// <param name="map">heightmap</param> |
1162 | public virtual void SendLayerData(float[] map) | 1194 | public virtual void SendLayerData(float[] map) |
1163 | { | 1195 | { |
1164 | Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData()); | 1196 | Util.FireAndForget(DoSendLayerData, m_scene.Heightmap.GetTerrainData(), "LLClientView.DoSendLayerData"); |
1165 | } | 1197 | } |
1166 | 1198 | ||
1167 | /// <summary> | 1199 | /// <summary> |
@@ -1373,7 +1405,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1373 | /// <param name="windSpeeds">16x16 array of wind speeds</param> | 1405 | /// <param name="windSpeeds">16x16 array of wind speeds</param> |
1374 | public virtual void SendWindData(Vector2[] windSpeeds) | 1406 | public virtual void SendWindData(Vector2[] windSpeeds) |
1375 | { | 1407 | { |
1376 | Util.FireAndForget(DoSendWindData, windSpeeds); | 1408 | Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData"); |
1377 | } | 1409 | } |
1378 | 1410 | ||
1379 | /// <summary> | 1411 | /// <summary> |
@@ -1382,7 +1414,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1382 | /// <param name="windSpeeds">16x16 array of cloud densities</param> | 1414 | /// <param name="windSpeeds">16x16 array of cloud densities</param> |
1383 | public virtual void SendCloudData(float[] cloudDensity) | 1415 | public virtual void SendCloudData(float[] cloudDensity) |
1384 | { | 1416 | { |
1385 | Util.FireAndForget(DoSendCloudData, cloudDensity); | 1417 | Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData"); |
1386 | } | 1418 | } |
1387 | 1419 | ||
1388 | /// <summary> | 1420 | /// <summary> |
@@ -3834,11 +3866,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3834 | /// </summary> | 3866 | /// </summary> |
3835 | public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) | 3867 | public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
3836 | { | 3868 | { |
3837 | //double priority = m_prioritizer.GetUpdatePriority(this, entity); | 3869 | if (entity.UUID == m_agentId && !updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) |
3838 | uint priority = m_prioritizer.GetUpdatePriority(this, entity); | 3870 | { |
3871 | ImprovedTerseObjectUpdatePacket packet | ||
3872 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
3839 | 3873 | ||
3840 | lock (m_entityUpdates.SyncRoot) | 3874 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; |
3841 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); | 3875 | packet.RegionData.TimeDilation = Utils.FloatToUInt16(1, 0.0f, 1.0f); |
3876 | packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | ||
3877 | packet.ObjectData[0] = CreateImprovedTerseBlock(entity, false); | ||
3878 | OutPacket(packet, ThrottleOutPacketType.Unknown, true); | ||
3879 | } | ||
3880 | else | ||
3881 | { | ||
3882 | //double priority = m_prioritizer.GetUpdatePriority(this, entity); | ||
3883 | uint priority = m_prioritizer.GetUpdatePriority(this, entity); | ||
3884 | |||
3885 | lock (m_entityUpdates.SyncRoot) | ||
3886 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); | ||
3887 | } | ||
3842 | } | 3888 | } |
3843 | 3889 | ||
3844 | /// <summary> | 3890 | /// <summary> |
@@ -5540,10 +5586,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5540 | AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); | 5586 | AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); |
5541 | AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); | 5587 | AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); |
5542 | AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); | 5588 | AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); |
5543 | AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); | 5589 | AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true); |
5544 | AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); | 5590 | AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true); |
5545 | AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); | 5591 | AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); |
5546 | AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); | 5592 | AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true); |
5547 | AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); | 5593 | AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); |
5548 | AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); | 5594 | AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); |
5549 | AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); | 5595 | AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); |
@@ -5728,8 +5774,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5728 | AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); | 5774 | AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); |
5729 | AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); | 5775 | AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); |
5730 | AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); | 5776 | AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); |
5731 | AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate); | 5777 | AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true); |
5732 | AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate); | 5778 | AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true); |
5733 | AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); | 5779 | AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); |
5734 | AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); | 5780 | AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); |
5735 | AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); | 5781 | AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); |
@@ -8079,7 +8125,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8079 | { | 8125 | { |
8080 | // This requests the asset if needed | 8126 | // This requests the asset if needed |
8081 | HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer); | 8127 | HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer); |
8082 | }); | 8128 | }, null, "LLClientView.HandleTransferRequest"); |
8129 | |||
8083 | return true; | 8130 | return true; |
8084 | } | 8131 | } |
8085 | } | 8132 | } |
@@ -12786,8 +12833,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12786 | 12833 | ||
12787 | public struct PacketProcessor | 12834 | public struct PacketProcessor |
12788 | { | 12835 | { |
12789 | public PacketMethod method; | 12836 | /// <summary> |
12790 | public bool Async; | 12837 | /// Packet handling method. |
12838 | /// </summary> | ||
12839 | public PacketMethod method { get; set; } | ||
12840 | |||
12841 | /// <summary> | ||
12842 | /// Should this packet be handled asynchronously? | ||
12843 | /// </summary> | ||
12844 | public bool Async { get; set; } | ||
12845 | |||
12846 | /// <summary> | ||
12847 | /// If async is true, should this packet be handled in the async engine or given directly to a threadpool | ||
12848 | /// thread? | ||
12849 | /// </summary> | ||
12850 | public bool InEngine { get; set; } | ||
12791 | } | 12851 | } |
12792 | 12852 | ||
12793 | public class AsyncPacketProcess | 12853 | public class AsyncPacketProcess |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index d8ca343..8f14806 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | |||
@@ -97,7 +97,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
97 | { | 97 | { |
98 | m_throttleDebugLevel = value; | 98 | m_throttleDebugLevel = value; |
99 | m_throttleClient.DebugLevel = m_throttleDebugLevel; | 99 | m_throttleClient.DebugLevel = m_throttleDebugLevel; |
100 | m_throttleCategory.DebugLevel = m_throttleDebugLevel; | ||
101 | foreach (TokenBucket tb in m_throttleCategories) | 100 | foreach (TokenBucket tb in m_throttleCategories) |
102 | tb.DebugLevel = m_throttleDebugLevel; | 101 | tb.DebugLevel = m_throttleDebugLevel; |
103 | } | 102 | } |
@@ -172,8 +171,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
172 | get { return m_throttleClient; } | 171 | get { return m_throttleClient; } |
173 | } | 172 | } |
174 | 173 | ||
175 | /// <summary>Throttle bucket for this agent's connection</summary> | ||
176 | private readonly TokenBucket m_throttleCategory; | ||
177 | /// <summary>Throttle buckets for each packet category</summary> | 174 | /// <summary>Throttle buckets for each packet category</summary> |
178 | private readonly TokenBucket[] m_throttleCategories; | 175 | private readonly TokenBucket[] m_throttleCategories; |
179 | /// <summary>Outgoing queues for throttled packets</summary> | 176 | /// <summary>Outgoing queues for throttled packets</summary> |
@@ -232,13 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
232 | m_throttleClient | 229 | m_throttleClient |
233 | = new AdaptiveTokenBucket( | 230 | = new AdaptiveTokenBucket( |
234 | string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name), | 231 | string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name), |
235 | parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled); | 232 | parentThrottle, 0, rates.Total, rates.AdaptiveThrottlesEnabled); |
236 | |||
237 | // Create a token bucket throttle for the total category with the client bucket as a throttle | ||
238 | m_throttleCategory | ||
239 | = new TokenBucket( | ||
240 | string.Format("total throttle for {0} in {1}", AgentID, server.Scene.Name), | ||
241 | m_throttleClient, 0); | ||
242 | 233 | ||
243 | // Create an array of token buckets for this clients different throttle categories | 234 | // Create an array of token buckets for this clients different throttle categories |
244 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 235 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
@@ -256,7 +247,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
256 | m_throttleCategories[i] | 247 | m_throttleCategories[i] |
257 | = new TokenBucket( | 248 | = new TokenBucket( |
258 | string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name), | 249 | string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name), |
259 | m_throttleCategory, rates.GetRate(type)); | 250 | m_throttleClient, rates.GetRate(type), 0); |
260 | } | 251 | } |
261 | 252 | ||
262 | // Default the retransmission timeout to one second | 253 | // Default the retransmission timeout to one second |
@@ -301,7 +292,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
301 | m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | 292 | m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
302 | m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; | 293 | m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; |
303 | m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | 294 | m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; |
304 | m_info.totalThrottle = (int)m_throttleCategory.DripRate; | 295 | m_info.totalThrottle = (int)m_throttleClient.DripRate; |
296 | m_info.targetThrottle = (int)m_throttleClient.TargetDripRate; | ||
305 | m_info.maxThrottle = (int)m_throttleClient.MaxDripRate; | 297 | m_info.maxThrottle = (int)m_throttleClient.MaxDripRate; |
306 | 298 | ||
307 | return m_info; | 299 | return m_info; |
@@ -320,6 +312,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
320 | } | 312 | } |
321 | 313 | ||
322 | /// <summary> | 314 | /// <summary> |
315 | /// Get the total number of pakcets queued for this client. | ||
316 | /// </summary> | ||
317 | /// <returns></returns> | ||
318 | public int GetTotalPacketsQueuedCount() | ||
319 | { | ||
320 | int total = 0; | ||
321 | |||
322 | for (int i = 0; i <= (int)ThrottleOutPacketType.Asset; i++) | ||
323 | total += m_packetOutboxes[i].Count; | ||
324 | |||
325 | return total; | ||
326 | } | ||
327 | |||
328 | /// <summary> | ||
329 | /// Get the number of packets queued for the given throttle type. | ||
330 | /// </summary> | ||
331 | /// <returns></returns> | ||
332 | /// <param name="throttleType"></param> | ||
333 | public int GetPacketsQueuedCount(ThrottleOutPacketType throttleType) | ||
334 | { | ||
335 | if ((int)throttleType > 0) | ||
336 | return m_packetOutboxes[(int)throttleType].Count; | ||
337 | else | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | /// <summary> | ||
323 | /// Return statistics information about client packet queues. | 342 | /// Return statistics information about client packet queues. |
324 | /// </summary> | 343 | /// </summary> |
325 | /// <remarks> | 344 | /// <remarks> |
@@ -388,6 +407,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
388 | int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | 407 | int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; |
389 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); | 408 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); |
390 | 409 | ||
410 | if (ThrottleDebugLevel > 0) | ||
411 | { | ||
412 | long total = resend + land + wind + cloud + task + texture + asset; | ||
413 | m_log.DebugFormat( | ||
414 | "[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}", | ||
415 | AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total); | ||
416 | } | ||
417 | |||
391 | // Make sure none of the throttles are set below our packet MTU, | 418 | // Make sure none of the throttles are set below our packet MTU, |
392 | // otherwise a throttle could become permanently clogged | 419 | // otherwise a throttle could become permanently clogged |
393 | resend = Math.Max(resend, LLUDPServer.MTU); | 420 | resend = Math.Max(resend, LLUDPServer.MTU); |
@@ -407,11 +434,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
407 | //int total = resend + land + wind + cloud + task + texture + asset; | 434 | //int total = resend + land + wind + cloud + task + texture + asset; |
408 | 435 | ||
409 | if (ThrottleDebugLevel > 0) | 436 | if (ThrottleDebugLevel > 0) |
437 | { | ||
438 | long total = resend + land + wind + cloud + task + texture + asset; | ||
410 | m_log.DebugFormat( | 439 | m_log.DebugFormat( |
411 | "[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}", | 440 | "[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}", |
412 | AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset); | 441 | AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total); |
442 | } | ||
413 | 443 | ||
414 | // Update the token buckets with new throttle values | 444 | // Update the token buckets with new throttle values |
445 | if (m_throttleClient.AdaptiveEnabled) | ||
446 | { | ||
447 | long total = resend + land + wind + cloud + task + texture + asset; | ||
448 | m_throttleClient.TargetDripRate = total; | ||
449 | } | ||
450 | |||
415 | TokenBucket bucket; | 451 | TokenBucket bucket; |
416 | 452 | ||
417 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; | 453 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
@@ -696,7 +732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
696 | if (!m_udpServer.OqrEngine.IsRunning) | 732 | if (!m_udpServer.OqrEngine.IsRunning) |
697 | { | 733 | { |
698 | // Asynchronously run the callback | 734 | // Asynchronously run the callback |
699 | Util.FireAndForget(FireQueueEmpty, categories); | 735 | Util.FireAndForget(FireQueueEmpty, categories, "LLUDPClient.BeginFireQueueEmpty"); |
700 | } | 736 | } |
701 | else | 737 | else |
702 | { | 738 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 9757d35..2f97516 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -34,7 +34,6 @@ using System.Net.Sockets; | |||
34 | using System.Reflection; | 34 | using System.Reflection; |
35 | using System.Threading; | 35 | using System.Threading; |
36 | using log4net; | 36 | using log4net; |
37 | using NDesk.Options; | ||
38 | using Nini.Config; | 37 | using Nini.Config; |
39 | using OpenMetaverse.Packets; | 38 | using OpenMetaverse.Packets; |
40 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
@@ -222,6 +221,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
222 | /// </summary> | 221 | /// </summary> |
223 | public int DefaultClientPacketDebugLevel { get; set; } | 222 | public int DefaultClientPacketDebugLevel { get; set; } |
224 | 223 | ||
224 | /// <summary> | ||
225 | /// If set then all inbound agent updates are discarded. For debugging purposes. | ||
226 | /// discard agent update. | ||
227 | /// </summary> | ||
228 | public bool DiscardInboundAgentUpdates { get; set; } | ||
229 | |||
225 | /// <summary>The measured resolution of Environment.TickCount</summary> | 230 | /// <summary>The measured resolution of Environment.TickCount</summary> |
226 | public readonly float TickCountResolution; | 231 | public readonly float TickCountResolution; |
227 | 232 | ||
@@ -238,12 +243,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
238 | /// <summary>Incoming packets that are awaiting handling</summary> | 243 | /// <summary>Incoming packets that are awaiting handling</summary> |
239 | private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); | 244 | private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); |
240 | 245 | ||
241 | /// <summary></summary> | ||
242 | //private UDPClientCollection m_clients = new UDPClientCollection(); | ||
243 | /// <summary>Bandwidth throttle for this UDP server</summary> | 246 | /// <summary>Bandwidth throttle for this UDP server</summary> |
244 | protected TokenBucket m_throttle; | 247 | public TokenBucket Throttle { get; private set; } |
245 | 248 | ||
246 | /// <summary>Bandwidth throttle rates for this UDP server</summary> | 249 | /// <summary>Per client throttle rates enforced by this server</summary> |
250 | /// <remarks> | ||
251 | /// If the total rate is non-zero, then this is the maximum total throttle setting that any client can ever have. | ||
252 | /// The other rates (resend, asset, etc.) are the defaults for a new client and can be changed (and usually | ||
253 | /// do get changed immediately). They do not need to sum to the total. | ||
254 | /// </remarks> | ||
247 | public ThrottleRates ThrottleRates { get; private set; } | 255 | public ThrottleRates ThrottleRates { get; private set; } |
248 | 256 | ||
249 | /// <summary>Manages authentication for agent circuits</summary> | 257 | /// <summary>Manages authentication for agent circuits</summary> |
@@ -356,6 +364,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
356 | private IClientAPI m_currentIncomingClient; | 364 | private IClientAPI m_currentIncomingClient; |
357 | 365 | ||
358 | /// <summary> | 366 | /// <summary> |
367 | /// Queue some low priority but potentially high volume async requests so that they don't overwhelm available | ||
368 | /// threadpool threads. | ||
369 | /// </summary> | ||
370 | public IncomingPacketAsyncHandlingEngine IpahEngine { get; private set; } | ||
371 | |||
372 | /// <summary> | ||
359 | /// Experimental facility to run queue empty processing within a controlled number of threads rather than | 373 | /// Experimental facility to run queue empty processing within a controlled number of threads rather than |
360 | /// requiring massive numbers of short-lived threads from the threadpool when there are a high number of | 374 | /// requiring massive numbers of short-lived threads from the threadpool when there are a high number of |
361 | /// connections. | 375 | /// connections. |
@@ -439,13 +453,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
439 | // = new TokenBucket( | 453 | // = new TokenBucket( |
440 | // string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps); | 454 | // string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps); |
441 | 455 | ||
442 | m_throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps); | 456 | Throttle = new TokenBucket("server throttle bucket", null, 0, sceneThrottleBps); |
443 | 457 | ||
444 | ThrottleRates = new ThrottleRates(configSource); | 458 | ThrottleRates = new ThrottleRates(configSource); |
445 | 459 | ||
446 | if (usePools) | 460 | if (usePools) |
447 | EnablePools(); | 461 | EnablePools(); |
448 | 462 | ||
463 | IpahEngine = new IncomingPacketAsyncHandlingEngine(this); | ||
449 | OqrEngine = new OutgoingQueueRefillEngine(this); | 464 | OqrEngine = new OutgoingQueueRefillEngine(this); |
450 | } | 465 | } |
451 | 466 | ||
@@ -453,12 +468,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
453 | { | 468 | { |
454 | StartInbound(); | 469 | StartInbound(); |
455 | StartOutbound(); | 470 | StartOutbound(); |
471 | IpahEngine.Start(); | ||
456 | OqrEngine.Start(); | 472 | OqrEngine.Start(); |
457 | 473 | ||
458 | m_elapsedMSSinceLastStatReport = Environment.TickCount; | 474 | m_elapsedMSSinceLastStatReport = Environment.TickCount; |
459 | } | 475 | } |
460 | 476 | ||
461 | private void StartInbound() | 477 | public void StartInbound() |
462 | { | 478 | { |
463 | m_log.InfoFormat( | 479 | m_log.InfoFormat( |
464 | "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", | 480 | "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", |
@@ -467,7 +483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
467 | base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); | 483 | base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); |
468 | 484 | ||
469 | // This thread will process the packets received that are placed on the packetInbox | 485 | // This thread will process the packets received that are placed on the packetInbox |
470 | Watchdog.StartThread( | 486 | WorkManager.StartThread( |
471 | IncomingPacketHandler, | 487 | IncomingPacketHandler, |
472 | string.Format("Incoming Packets ({0})", Scene.Name), | 488 | string.Format("Incoming Packets ({0})", Scene.Name), |
473 | ThreadPriority.Normal, | 489 | ThreadPriority.Normal, |
@@ -477,13 +493,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
477 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 493 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
478 | } | 494 | } |
479 | 495 | ||
480 | private new void StartOutbound() | 496 | public override void StartOutbound() |
481 | { | 497 | { |
482 | m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); | 498 | m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); |
483 | 499 | ||
484 | base.StartOutbound(); | 500 | base.StartOutbound(); |
485 | 501 | ||
486 | Watchdog.StartThread( | 502 | WorkManager.StartThread( |
487 | OutgoingPacketHandler, | 503 | OutgoingPacketHandler, |
488 | string.Format("Outgoing Packets ({0})", Scene.Name), | 504 | string.Format("Outgoing Packets ({0})", Scene.Name), |
489 | ThreadPriority.Normal, | 505 | ThreadPriority.Normal, |
@@ -498,10 +514,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
498 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name); | 514 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name); |
499 | base.StopOutbound(); | 515 | base.StopOutbound(); |
500 | base.StopInbound(); | 516 | base.StopInbound(); |
517 | IpahEngine.Stop(); | ||
501 | OqrEngine.Stop(); | 518 | OqrEngine.Stop(); |
502 | } | 519 | } |
503 | 520 | ||
504 | protected override bool EnablePools() | 521 | public override bool EnablePools() |
505 | { | 522 | { |
506 | if (!UsePools) | 523 | if (!UsePools) |
507 | { | 524 | { |
@@ -515,7 +532,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
515 | return false; | 532 | return false; |
516 | } | 533 | } |
517 | 534 | ||
518 | protected override bool DisablePools() | 535 | public override bool DisablePools() |
519 | { | 536 | { |
520 | if (UsePools) | 537 | if (UsePools) |
521 | { | 538 | { |
@@ -535,7 +552,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
535 | /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene | 552 | /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene |
536 | /// stats. | 553 | /// stats. |
537 | /// </summary> | 554 | /// </summary> |
538 | private void EnablePoolStats() | 555 | protected internal void EnablePoolStats() |
539 | { | 556 | { |
540 | m_poolCountStat | 557 | m_poolCountStat |
541 | = new Stat( | 558 | = new Stat( |
@@ -569,7 +586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
569 | /// <summary> | 586 | /// <summary> |
570 | /// Disables pool stats. | 587 | /// Disables pool stats. |
571 | /// </summary> | 588 | /// </summary> |
572 | private void DisablePoolStats() | 589 | protected internal void DisablePoolStats() |
573 | { | 590 | { |
574 | StatsManager.DeregisterStat(m_poolCountStat); | 591 | StatsManager.DeregisterStat(m_poolCountStat); |
575 | m_poolCountStat = null; | 592 | m_poolCountStat = null; |
@@ -683,434 +700,45 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
683 | StatType.Pull, | 700 | StatType.Pull, |
684 | stat => stat.Value = PacketPool.Instance.BlocksPooled, | 701 | stat => stat.Value = PacketPool.Instance.BlocksPooled, |
685 | StatVerbosity.Debug)); | 702 | StatVerbosity.Debug)); |
703 | |||
704 | StatsManager.RegisterStat( | ||
705 | new Stat( | ||
706 | "OutgoingPacketsQueuedCount", | ||
707 | "Packets queued for outgoing send", | ||
708 | "Number of queued outgoing packets across all connections", | ||
709 | "", | ||
710 | "clientstack", | ||
711 | Scene.Name, | ||
712 | StatType.Pull, | ||
713 | MeasuresOfInterest.AverageChangeOverTime, | ||
714 | stat => stat.Value = GetTotalQueuedOutgoingPackets(), | ||
715 | StatVerbosity.Info)); | ||
686 | 716 | ||
687 | // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by | 717 | // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by |
688 | // scene name | 718 | // scene name |
689 | if (UsePools) | 719 | if (UsePools) |
690 | EnablePoolStats(); | 720 | EnablePoolStats(); |
691 | 721 | ||
692 | MainConsole.Instance.Commands.AddCommand( | 722 | LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); |
693 | "Debug", false, "debug lludp packet", | 723 | commands.Register(); |
694 | "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]", | ||
695 | "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.", | ||
696 | "If level > 255 then all incoming and outgoing packets are logged.\n" | ||
697 | + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n" | ||
698 | + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n" | ||
699 | + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n" | ||
700 | + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n" | ||
701 | + "If level <= 0 then no packets are logged.\n" | ||
702 | + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n" | ||
703 | + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n" | ||
704 | + "In these cases, you cannot also specify an avatar name.\n" | ||
705 | + "If an avatar name is given then only packets from that avatar are logged.", | ||
706 | HandlePacketCommand); | ||
707 | |||
708 | MainConsole.Instance.Commands.AddCommand( | ||
709 | "Debug", false, "debug lludp data out", | ||
710 | "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"", | ||
711 | "Turn on debugging for final outgoing data to the given user's client.", | ||
712 | "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n" | ||
713 | + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n" | ||
714 | + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.", | ||
715 | HandleDataCommand); | ||
716 | |||
717 | MainConsole.Instance.Commands.AddCommand( | ||
718 | "Debug", false, "debug lludp drop", | ||
719 | "debug lludp drop <in|out> <add|remove> <packet-name>", | ||
720 | "Drop all in or outbound packets that match the given name", | ||
721 | "For test purposes.", | ||
722 | HandleDropCommand); | ||
723 | |||
724 | MainConsole.Instance.Commands.AddCommand( | ||
725 | "Debug", | ||
726 | false, | ||
727 | "debug lludp start", | ||
728 | "debug lludp start <in|out|all>", | ||
729 | "Control LLUDP packet processing.", | ||
730 | "No effect if packet processing has already started.\n" | ||
731 | + "in - start inbound processing.\n" | ||
732 | + "out - start outbound processing.\n" | ||
733 | + "all - start in and outbound processing.\n", | ||
734 | HandleStartCommand); | ||
735 | |||
736 | MainConsole.Instance.Commands.AddCommand( | ||
737 | "Debug", | ||
738 | false, | ||
739 | "debug lludp stop", | ||
740 | "debug lludp stop <in|out|all>", | ||
741 | "Stop LLUDP packet processing.", | ||
742 | "No effect if packet processing has already stopped.\n" | ||
743 | + "in - stop inbound processing.\n" | ||
744 | + "out - stop outbound processing.\n" | ||
745 | + "all - stop in and outbound processing.\n", | ||
746 | HandleStopCommand); | ||
747 | |||
748 | MainConsole.Instance.Commands.AddCommand( | ||
749 | "Debug", | ||
750 | false, | ||
751 | "debug lludp pool", | ||
752 | "debug lludp pool <on|off>", | ||
753 | "Turn object pooling within the lludp component on or off.", | ||
754 | HandlePoolCommand); | ||
755 | |||
756 | MainConsole.Instance.Commands.AddCommand( | ||
757 | "Debug", | ||
758 | false, | ||
759 | "debug lludp status", | ||
760 | "debug lludp status", | ||
761 | "Return status of LLUDP packet processing.", | ||
762 | HandleStatusCommand); | ||
763 | |||
764 | MainConsole.Instance.Commands.AddCommand( | ||
765 | "Debug", | ||
766 | false, | ||
767 | "debug lludp throttle log", | ||
768 | "debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>", | ||
769 | "Change debug logging level for throttles.", | ||
770 | "If level >= 0 then throttle debug logging is performed.\n" | ||
771 | + "If level <= 0 then no throttle debug logging is performed.", | ||
772 | HandleThrottleCommand); | ||
773 | |||
774 | MainConsole.Instance.Commands.AddCommand( | ||
775 | "Debug", | ||
776 | false, | ||
777 | "debug lludp throttle status", | ||
778 | "debug lludp throttle status <avatar-first-name> <avatar-last-name>", | ||
779 | "Return status information about throttles.", | ||
780 | HandleThrottleStatusCommand); | ||
781 | |||
782 | MainConsole.Instance.Commands.AddCommand( | ||
783 | "Debug", | ||
784 | false, | ||
785 | "debug lludp toggle agentupdate", | ||
786 | "debug lludp toggle agentupdate", | ||
787 | "Toggle whether agentupdate packets are processed or simply discarded.", | ||
788 | HandleAgentUpdateCommand); | ||
789 | } | ||
790 | |||
791 | private void HandleDataCommand(string module, string[] args) | ||
792 | { | ||
793 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
794 | return; | ||
795 | |||
796 | if (args.Length != 7) | ||
797 | { | ||
798 | MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>"); | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | int level; | ||
803 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level)) | ||
804 | return; | ||
805 | |||
806 | string firstName = args[5]; | ||
807 | string lastName = args[6]; | ||
808 | |||
809 | Scene.ForEachScenePresence(sp => | ||
810 | { | ||
811 | if (sp.Firstname == firstName && sp.Lastname == lastName) | ||
812 | { | ||
813 | MainConsole.Instance.OutputFormat( | ||
814 | "Data debug for {0} ({1}) set to {2} in {3}", | ||
815 | sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name); | ||
816 | |||
817 | ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level; | ||
818 | } | ||
819 | }); | ||
820 | } | 724 | } |
821 | 725 | ||
822 | private void HandleThrottleCommand(string module, string[] args) | 726 | public bool HandlesRegion(Location x) |
823 | { | ||
824 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
825 | return; | ||
826 | |||
827 | if (args.Length != 7) | ||
828 | { | ||
829 | MainConsole.Instance.OutputFormat("Usage: debug lludp throttle log <level> <avatar-first-name> <avatar-last-name>"); | ||
830 | return; | ||
831 | } | ||
832 | |||
833 | int level; | ||
834 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level)) | ||
835 | return; | ||
836 | |||
837 | string firstName = args[5]; | ||
838 | string lastName = args[6]; | ||
839 | |||
840 | Scene.ForEachScenePresence(sp => | ||
841 | { | ||
842 | if (sp.Firstname == firstName && sp.Lastname == lastName) | ||
843 | { | ||
844 | MainConsole.Instance.OutputFormat( | ||
845 | "Throttle log level for {0} ({1}) set to {2} in {3}", | ||
846 | sp.Name, sp.IsChildAgent ? "child" : "root", level, Scene.Name); | ||
847 | |||
848 | ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level; | ||
849 | } | ||
850 | }); | ||
851 | } | ||
852 | |||
853 | private void HandleThrottleStatusCommand(string module, string[] args) | ||
854 | { | ||
855 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
856 | return; | ||
857 | |||
858 | if (args.Length != 6) | ||
859 | { | ||
860 | MainConsole.Instance.OutputFormat("Usage: debug lludp throttle status <avatar-first-name> <avatar-last-name>"); | ||
861 | return; | ||
862 | } | ||
863 | |||
864 | string firstName = args[4]; | ||
865 | string lastName = args[5]; | ||
866 | |||
867 | Scene.ForEachScenePresence(sp => | ||
868 | { | ||
869 | if (sp.Firstname == firstName && sp.Lastname == lastName) | ||
870 | { | ||
871 | MainConsole.Instance.OutputFormat( | ||
872 | "Status for {0} ({1}) in {2}", | ||
873 | sp.Name, sp.IsChildAgent ? "child" : "root", Scene.Name); | ||
874 | |||
875 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
876 | MainConsole.Instance.OutputFormat("Adaptive throttle: {0}", udpClient.FlowThrottle.Enabled); | ||
877 | } | ||
878 | }); | ||
879 | } | ||
880 | |||
881 | private void HandlePacketCommand(string module, string[] args) | ||
882 | { | ||
883 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
884 | return; | ||
885 | |||
886 | bool setAsDefaultLevel = false; | ||
887 | bool setAll = false; | ||
888 | OptionSet optionSet = new OptionSet() | ||
889 | .Add("default", o => setAsDefaultLevel = (o != null)) | ||
890 | .Add("all", o => setAll = (o != null)); | ||
891 | List<string> filteredArgs = optionSet.Parse(args); | ||
892 | |||
893 | string name = null; | ||
894 | |||
895 | if (filteredArgs.Count == 6) | ||
896 | { | ||
897 | if (!(setAsDefaultLevel || setAll)) | ||
898 | { | ||
899 | name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]); | ||
900 | } | ||
901 | else | ||
902 | { | ||
903 | MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level"); | ||
904 | return; | ||
905 | } | ||
906 | } | ||
907 | |||
908 | if (filteredArgs.Count > 3) | ||
909 | { | ||
910 | int newDebug; | ||
911 | if (int.TryParse(filteredArgs[3], out newDebug)) | ||
912 | { | ||
913 | if (setAsDefaultLevel || setAll) | ||
914 | { | ||
915 | DefaultClientPacketDebugLevel = newDebug; | ||
916 | |||
917 | MainConsole.Instance.OutputFormat( | ||
918 | "Packet debug for {0} clients set to {1} in {2}", | ||
919 | (setAll ? "all" : "future"), DefaultClientPacketDebugLevel, Scene.Name); | ||
920 | |||
921 | if (setAll) | ||
922 | { | ||
923 | Scene.ForEachScenePresence(sp => | ||
924 | { | ||
925 | MainConsole.Instance.OutputFormat( | ||
926 | "Packet debug for {0} ({1}) set to {2} in {3}", | ||
927 | sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name); | ||
928 | |||
929 | sp.ControllingClient.DebugPacketLevel = newDebug; | ||
930 | }); | ||
931 | } | ||
932 | } | ||
933 | else | ||
934 | { | ||
935 | Scene.ForEachScenePresence(sp => | ||
936 | { | ||
937 | if (name == null || sp.Name == name) | ||
938 | { | ||
939 | MainConsole.Instance.OutputFormat( | ||
940 | "Packet debug for {0} ({1}) set to {2} in {3}", | ||
941 | sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, Scene.Name); | ||
942 | |||
943 | sp.ControllingClient.DebugPacketLevel = newDebug; | ||
944 | } | ||
945 | }); | ||
946 | } | ||
947 | } | ||
948 | else | ||
949 | { | ||
950 | MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]"); | ||
951 | } | ||
952 | } | ||
953 | } | ||
954 | |||
955 | private void HandleDropCommand(string module, string[] args) | ||
956 | { | ||
957 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
958 | return; | ||
959 | |||
960 | if (args.Length != 6) | ||
961 | { | ||
962 | MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>"); | ||
963 | return; | ||
964 | } | ||
965 | |||
966 | string direction = args[3]; | ||
967 | string subCommand = args[4]; | ||
968 | string packetName = args[5]; | ||
969 | |||
970 | if (subCommand == "add") | ||
971 | { | ||
972 | MainConsole.Instance.OutputFormat( | ||
973 | "Adding packet {0} to {1} drop list for all connections in {2}", direction, packetName, Scene.Name); | ||
974 | |||
975 | Scene.ForEachScenePresence( | ||
976 | sp => | ||
977 | { | ||
978 | LLClientView llcv = (LLClientView)sp.ControllingClient; | ||
979 | |||
980 | if (direction == "in") | ||
981 | llcv.AddInPacketToDropSet(packetName); | ||
982 | else if (direction == "out") | ||
983 | llcv.AddOutPacketToDropSet(packetName); | ||
984 | } | ||
985 | ); | ||
986 | } | ||
987 | else if (subCommand == "remove") | ||
988 | { | ||
989 | MainConsole.Instance.OutputFormat( | ||
990 | "Removing packet {0} from {1} drop list for all connections in {2}", direction, packetName, Scene.Name); | ||
991 | |||
992 | Scene.ForEachScenePresence( | ||
993 | sp => | ||
994 | { | ||
995 | LLClientView llcv = (LLClientView)sp.ControllingClient; | ||
996 | |||
997 | if (direction == "in") | ||
998 | llcv.RemoveInPacketFromDropSet(packetName); | ||
999 | else if (direction == "out") | ||
1000 | llcv.RemoveOutPacketFromDropSet(packetName); | ||
1001 | } | ||
1002 | ); | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | private void HandleStartCommand(string module, string[] args) | ||
1007 | { | ||
1008 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
1009 | return; | ||
1010 | |||
1011 | if (args.Length != 4) | ||
1012 | { | ||
1013 | MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>"); | ||
1014 | return; | ||
1015 | } | ||
1016 | |||
1017 | string subCommand = args[3]; | ||
1018 | |||
1019 | if (subCommand == "in" || subCommand == "all") | ||
1020 | StartInbound(); | ||
1021 | |||
1022 | if (subCommand == "out" || subCommand == "all") | ||
1023 | StartOutbound(); | ||
1024 | } | ||
1025 | |||
1026 | private void HandleStopCommand(string module, string[] args) | ||
1027 | { | 727 | { |
1028 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | 728 | return x == m_location; |
1029 | return; | ||
1030 | |||
1031 | if (args.Length != 4) | ||
1032 | { | ||
1033 | MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>"); | ||
1034 | return; | ||
1035 | } | ||
1036 | |||
1037 | string subCommand = args[3]; | ||
1038 | |||
1039 | if (subCommand == "in" || subCommand == "all") | ||
1040 | StopInbound(); | ||
1041 | |||
1042 | if (subCommand == "out" || subCommand == "all") | ||
1043 | StopOutbound(); | ||
1044 | } | 729 | } |
1045 | 730 | ||
1046 | private void HandlePoolCommand(string module, string[] args) | 731 | public int GetTotalQueuedOutgoingPackets() |
1047 | { | 732 | { |
1048 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | 733 | int total = 0; |
1049 | return; | ||
1050 | 734 | ||
1051 | if (args.Length != 4) | 735 | foreach (ScenePresence sp in Scene.GetScenePresences()) |
1052 | { | 736 | { |
1053 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | 737 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; |
1054 | return; | 738 | total += udpClient.GetTotalPacketsQueuedCount(); |
1055 | } | 739 | } |
1056 | 740 | ||
1057 | string enabled = args[3]; | 741 | return total; |
1058 | |||
1059 | if (enabled == "on") | ||
1060 | { | ||
1061 | if (EnablePools()) | ||
1062 | { | ||
1063 | EnablePoolStats(); | ||
1064 | MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", Scene.Name); | ||
1065 | } | ||
1066 | } | ||
1067 | else if (enabled == "off") | ||
1068 | { | ||
1069 | if (DisablePools()) | ||
1070 | { | ||
1071 | DisablePoolStats(); | ||
1072 | MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", Scene.Name); | ||
1073 | } | ||
1074 | } | ||
1075 | else | ||
1076 | { | ||
1077 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | bool m_discardAgentUpdates; | ||
1082 | |||
1083 | private void HandleAgentUpdateCommand(string module, string[] args) | ||
1084 | { | ||
1085 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
1086 | return; | ||
1087 | |||
1088 | m_discardAgentUpdates = !m_discardAgentUpdates; | ||
1089 | |||
1090 | MainConsole.Instance.OutputFormat( | ||
1091 | "Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, Scene.Name); | ||
1092 | } | ||
1093 | |||
1094 | private void HandleStatusCommand(string module, string[] args) | ||
1095 | { | ||
1096 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != Scene) | ||
1097 | return; | ||
1098 | |||
1099 | MainConsole.Instance.OutputFormat( | ||
1100 | "IN LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningInbound ? "enabled" : "disabled"); | ||
1101 | |||
1102 | MainConsole.Instance.OutputFormat( | ||
1103 | "OUT LLUDP packet processing for {0} is {1}", Scene.Name, IsRunningOutbound ? "enabled" : "disabled"); | ||
1104 | |||
1105 | MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", Scene.Name, UsePools ? "on" : "off"); | ||
1106 | |||
1107 | MainConsole.Instance.OutputFormat( | ||
1108 | "Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel); | ||
1109 | } | ||
1110 | |||
1111 | public bool HandlesRegion(Location x) | ||
1112 | { | ||
1113 | return x == m_location; | ||
1114 | } | 742 | } |
1115 | 743 | ||
1116 | // public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) | 744 | // public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) |
@@ -1279,6 +907,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1279 | // packet so that it isn't sent before a queued update packet. | 907 | // packet so that it isn't sent before a queued update packet. |
1280 | bool forceQueue = (type == PacketType.KillObject); | 908 | bool forceQueue = (type == PacketType.KillObject); |
1281 | 909 | ||
910 | // if (type == PacketType.ImprovedTerseObjectUpdate) | ||
911 | // { | ||
912 | // m_log.DebugFormat("Direct send ITOU to {0} in {1}", udpClient.AgentID, Scene.Name); | ||
913 | // SendPacketFinal(outgoingPacket); | ||
914 | // return false; | ||
915 | // } | ||
916 | // else | ||
917 | // { | ||
1282 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue)) | 918 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue)) |
1283 | { | 919 | { |
1284 | SendPacketFinal(outgoingPacket); | 920 | SendPacketFinal(outgoingPacket); |
@@ -1288,6 +924,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1288 | { | 924 | { |
1289 | return false; | 925 | return false; |
1290 | } | 926 | } |
927 | // } | ||
1291 | 928 | ||
1292 | #endregion Queue or Send | 929 | #endregion Queue or Send |
1293 | } | 930 | } |
@@ -1363,7 +1000,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1363 | // Fire this out on a different thread so that we don't hold up outgoing packet processing for | 1000 | // Fire this out on a different thread so that we don't hold up outgoing packet processing for |
1364 | // everybody else if this is being called due to an ack timeout. | 1001 | // everybody else if this is being called due to an ack timeout. |
1365 | // This is the same as processing as the async process of a logout request. | 1002 | // This is the same as processing as the async process of a logout request. |
1366 | Util.FireAndForget(o => DeactivateClientDueToTimeout(client, timeoutTicks)); | 1003 | Util.FireAndForget( |
1004 | o => DeactivateClientDueToTimeout(client, timeoutTicks), null, "LLUDPServer.DeactivateClientDueToTimeout"); | ||
1367 | 1005 | ||
1368 | return; | 1006 | return; |
1369 | } | 1007 | } |
@@ -1597,7 +1235,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1597 | // buffer. | 1235 | // buffer. |
1598 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | 1236 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; |
1599 | 1237 | ||
1600 | Util.FireAndForget(HandleUseCircuitCode, array); | 1238 | Util.FireAndForget(HandleUseCircuitCode, array, "LLUDPServer.HandleUseCircuitCode"); |
1601 | 1239 | ||
1602 | return; | 1240 | return; |
1603 | } | 1241 | } |
@@ -1610,7 +1248,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1610 | // buffer. | 1248 | // buffer. |
1611 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | 1249 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; |
1612 | 1250 | ||
1613 | Util.FireAndForget(HandleCompleteMovementIntoRegion, array); | 1251 | Util.FireAndForget( |
1252 | HandleCompleteMovementIntoRegion, array, "LLUDPServer.HandleCompleteMovementIntoRegion"); | ||
1614 | 1253 | ||
1615 | return; | 1254 | return; |
1616 | } | 1255 | } |
@@ -1732,7 +1371,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1732 | 1371 | ||
1733 | if (packet.Type == PacketType.AgentUpdate) | 1372 | if (packet.Type == PacketType.AgentUpdate) |
1734 | { | 1373 | { |
1735 | if (m_discardAgentUpdates) | 1374 | if (DiscardInboundAgentUpdates) |
1736 | return; | 1375 | return; |
1737 | 1376 | ||
1738 | ((LLClientView)client).TotalAgentUpdates++; | 1377 | ((LLClientView)client).TotalAgentUpdates++; |
@@ -2140,7 +1779,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2140 | { | 1779 | { |
2141 | if (!Scene.TryGetClient(agentID, out client)) | 1780 | if (!Scene.TryGetClient(agentID, out client)) |
2142 | { | 1781 | { |
2143 | LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); | 1782 | LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, Throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); |
2144 | 1783 | ||
2145 | client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); | 1784 | client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); |
2146 | client.OnLogout += LogoutHandler; | 1785 | client.OnLogout += LogoutHandler; |
@@ -2183,6 +1822,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2183 | 1822 | ||
2184 | private void IncomingPacketHandler() | 1823 | private void IncomingPacketHandler() |
2185 | { | 1824 | { |
1825 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
1826 | |||
2186 | // Set this culture for the thread that incoming packets are received | 1827 | // Set this culture for the thread that incoming packets are received |
2187 | // on to en-US to avoid number parsing issues | 1828 | // on to en-US to avoid number parsing issues |
2188 | Culture.SetCurrentCulture(); | 1829 | Culture.SetCurrentCulture(); |
@@ -2228,6 +1869,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2228 | 1869 | ||
2229 | private void OutgoingPacketHandler() | 1870 | private void OutgoingPacketHandler() |
2230 | { | 1871 | { |
1872 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
1873 | |||
2231 | // Set this culture for the thread that outgoing packets are sent | 1874 | // Set this culture for the thread that outgoing packets are sent |
2232 | // on to en-US to avoid number parsing issues | 1875 | // on to en-US to avoid number parsing issues |
2233 | Culture.SetCurrentCulture(); | 1876 | Culture.SetCurrentCulture(); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs new file mode 100644 index 0000000..e0398d5 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs | |||
@@ -0,0 +1,762 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using NDesk.Options; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Framework.Console; | ||
34 | using OpenSim.Region.Framework.Scenes; | ||
35 | |||
36 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
37 | { | ||
38 | public class LLUDPServerCommands | ||
39 | { | ||
40 | private ICommandConsole m_console; | ||
41 | private LLUDPServer m_udpServer; | ||
42 | |||
43 | public LLUDPServerCommands(ICommandConsole console, LLUDPServer udpServer) | ||
44 | { | ||
45 | m_console = console; | ||
46 | m_udpServer = udpServer; | ||
47 | } | ||
48 | |||
49 | public void Register() | ||
50 | { | ||
51 | m_console.Commands.AddCommand( | ||
52 | "Comms", false, "show server throttles", | ||
53 | "show server throttles", | ||
54 | "Show information about server throttles", | ||
55 | HandleShowServerThrottlesCommand); | ||
56 | |||
57 | m_console.Commands.AddCommand( | ||
58 | "Debug", false, "debug lludp packet", | ||
59 | "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]", | ||
60 | "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.", | ||
61 | "If level > 255 then all incoming and outgoing packets are logged.\n" | ||
62 | + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n" | ||
63 | + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n" | ||
64 | + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n" | ||
65 | + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n" | ||
66 | + "If level <= 0 then no packets are logged.\n" | ||
67 | + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n" | ||
68 | + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n" | ||
69 | + "In these cases, you cannot also specify an avatar name.\n" | ||
70 | + "If an avatar name is given then only packets from that avatar are logged.", | ||
71 | HandlePacketCommand); | ||
72 | |||
73 | m_console.Commands.AddCommand( | ||
74 | "Debug", false, "debug lludp data out", | ||
75 | "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"", | ||
76 | "Turn on debugging for final outgoing data to the given user's client.", | ||
77 | "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n" | ||
78 | + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n" | ||
79 | + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.", | ||
80 | HandleDataCommand); | ||
81 | |||
82 | m_console.Commands.AddCommand( | ||
83 | "Debug", false, "debug lludp drop", | ||
84 | "debug lludp drop <in|out> <add|remove> <packet-name>", | ||
85 | "Drop all in or outbound packets that match the given name", | ||
86 | "For test purposes.", | ||
87 | HandleDropCommand); | ||
88 | |||
89 | m_console.Commands.AddCommand( | ||
90 | "Debug", | ||
91 | false, | ||
92 | "debug lludp start", | ||
93 | "debug lludp start <in|out|all>", | ||
94 | "Control LLUDP packet processing.", | ||
95 | "No effect if packet processing has already started.\n" | ||
96 | + "in - start inbound processing.\n" | ||
97 | + "out - start outbound processing.\n" | ||
98 | + "all - start in and outbound processing.\n", | ||
99 | HandleStartCommand); | ||
100 | |||
101 | m_console.Commands.AddCommand( | ||
102 | "Debug", | ||
103 | false, | ||
104 | "debug lludp stop", | ||
105 | "debug lludp stop <in|out|all>", | ||
106 | "Stop LLUDP packet processing.", | ||
107 | "No effect if packet processing has already stopped.\n" | ||
108 | + "in - stop inbound processing.\n" | ||
109 | + "out - stop outbound processing.\n" | ||
110 | + "all - stop in and outbound processing.\n", | ||
111 | HandleStopCommand); | ||
112 | |||
113 | m_console.Commands.AddCommand( | ||
114 | "Debug", | ||
115 | false, | ||
116 | "debug lludp pool", | ||
117 | "debug lludp pool <on|off>", | ||
118 | "Turn object pooling within the lludp component on or off.", | ||
119 | HandlePoolCommand); | ||
120 | |||
121 | m_console.Commands.AddCommand( | ||
122 | "Debug", | ||
123 | false, | ||
124 | "debug lludp status", | ||
125 | "debug lludp status", | ||
126 | "Return status of LLUDP packet processing.", | ||
127 | HandleStatusCommand); | ||
128 | |||
129 | m_console.Commands.AddCommand( | ||
130 | "Debug", | ||
131 | false, | ||
132 | "debug lludp throttles log", | ||
133 | "debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]", | ||
134 | "Change debug logging level for throttles.", | ||
135 | "If level >= 0 then throttle debug logging is performed.\n" | ||
136 | + "If level <= 0 then no throttle debug logging is performed.", | ||
137 | HandleThrottleCommand); | ||
138 | |||
139 | m_console.Commands.AddCommand( | ||
140 | "Debug", | ||
141 | false, | ||
142 | "debug lludp throttles get", | ||
143 | "debug lludp throttles get [<avatar-first-name> <avatar-last-name>]", | ||
144 | "Return debug settings for throttles.", | ||
145 | "adaptive - true/false, controls adaptive throttle setting.\n" | ||
146 | + "request - request drip rate in kbps.\n" | ||
147 | + "max - the max kbps throttle allowed for the specified existing clients. Use 'debug lludp get new-client-throttle-max' to see the setting for new clients.\n", | ||
148 | HandleThrottleGetCommand); | ||
149 | |||
150 | m_console.Commands.AddCommand( | ||
151 | "Debug", | ||
152 | false, | ||
153 | "debug lludp throttles set", | ||
154 | "debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]", | ||
155 | "Set a throttle parameter for the given client.", | ||
156 | "adaptive - true/false, controls adaptive throttle setting.\n" | ||
157 | + "current - current drip rate in kbps.\n" | ||
158 | + "request - requested drip rate in kbps.\n" | ||
159 | + "max - the max kbps throttle allowed for the specified existing clients. Use 'debug lludp set new-client-throttle-max' to change the settings for new clients.\n", | ||
160 | HandleThrottleSetCommand); | ||
161 | |||
162 | m_console.Commands.AddCommand( | ||
163 | "Debug", | ||
164 | false, | ||
165 | "debug lludp get", | ||
166 | "debug lludp get", | ||
167 | "Get debug parameters for the server.", | ||
168 | "max-scene-throttle - the current max cumulative kbps provided for this scene to clients.\n" | ||
169 | + "max-new-client-throttle - the max kbps throttle allowed to new clients. Use 'debug lludp throttles get max' to see the settings for existing clients.", | ||
170 | HandleGetCommand); | ||
171 | |||
172 | m_console.Commands.AddCommand( | ||
173 | "Debug", | ||
174 | false, | ||
175 | "debug lludp set", | ||
176 | "debug lludp set <param> <value>", | ||
177 | "Set a parameter for the server.", | ||
178 | "max-scene-throttle - the current max cumulative kbps provided for this scene to clients.\n" | ||
179 | + "max-new-client-throttle - the max kbps throttle allowed to each new client. Use 'debug lludp throttles set max' to set for existing clients.", | ||
180 | HandleSetCommand); | ||
181 | |||
182 | m_console.Commands.AddCommand( | ||
183 | "Debug", | ||
184 | false, | ||
185 | "debug lludp toggle agentupdate", | ||
186 | "debug lludp toggle agentupdate", | ||
187 | "Toggle whether agentupdate packets are processed or simply discarded.", | ||
188 | HandleAgentUpdateCommand); | ||
189 | } | ||
190 | |||
191 | private void HandleShowServerThrottlesCommand(string module, string[] args) | ||
192 | { | ||
193 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
194 | return; | ||
195 | |||
196 | m_console.OutputFormat("Throttles for {0}", m_udpServer.Scene.Name); | ||
197 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
198 | cdl.AddRow("Adaptive throttles", m_udpServer.ThrottleRates.AdaptiveThrottlesEnabled); | ||
199 | |||
200 | long maxSceneDripRate = m_udpServer.Throttle.MaxDripRate; | ||
201 | cdl.AddRow( | ||
202 | "Max scene throttle", | ||
203 | maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset"); | ||
204 | |||
205 | int maxClientDripRate = m_udpServer.ThrottleRates.Total; | ||
206 | cdl.AddRow( | ||
207 | "Max new client throttle", | ||
208 | maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset"); | ||
209 | |||
210 | m_console.Output(cdl.ToString()); | ||
211 | |||
212 | m_console.OutputFormat("{0}\n", GetServerThrottlesReport(m_udpServer)); | ||
213 | } | ||
214 | |||
215 | private string GetServerThrottlesReport(LLUDPServer udpServer) | ||
216 | { | ||
217 | StringBuilder report = new StringBuilder(); | ||
218 | |||
219 | report.AppendFormat( | ||
220 | "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n", | ||
221 | "Total", | ||
222 | "Resend", | ||
223 | "Land", | ||
224 | "Wind", | ||
225 | "Cloud", | ||
226 | "Task", | ||
227 | "Texture", | ||
228 | "Asset"); | ||
229 | |||
230 | report.AppendFormat( | ||
231 | "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n", | ||
232 | "kb/s", | ||
233 | "kb/s", | ||
234 | "kb/s", | ||
235 | "kb/s", | ||
236 | "kb/s", | ||
237 | "kb/s", | ||
238 | "kb/s", | ||
239 | "kb/s"); | ||
240 | |||
241 | ThrottleRates throttleRates = udpServer.ThrottleRates; | ||
242 | report.AppendFormat( | ||
243 | "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}", | ||
244 | (throttleRates.Total * 8) / 1000, | ||
245 | (throttleRates.Resend * 8) / 1000, | ||
246 | (throttleRates.Land * 8) / 1000, | ||
247 | (throttleRates.Wind * 8) / 1000, | ||
248 | (throttleRates.Cloud * 8) / 1000, | ||
249 | (throttleRates.Task * 8) / 1000, | ||
250 | (throttleRates.Texture * 8) / 1000, | ||
251 | (throttleRates.Asset * 8) / 1000); | ||
252 | |||
253 | return report.ToString(); | ||
254 | } | ||
255 | |||
256 | protected string GetColumnEntry(string entry, int maxLength, int columnPadding) | ||
257 | { | ||
258 | return string.Format( | ||
259 | "{0,-" + maxLength + "}{1,-" + columnPadding + "}", | ||
260 | entry.Length > maxLength ? entry.Substring(0, maxLength) : entry, | ||
261 | ""); | ||
262 | } | ||
263 | |||
264 | private void HandleDataCommand(string module, string[] args) | ||
265 | { | ||
266 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
267 | return; | ||
268 | |||
269 | if (args.Length != 7) | ||
270 | { | ||
271 | MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>"); | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | int level; | ||
276 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level)) | ||
277 | return; | ||
278 | |||
279 | string firstName = args[5]; | ||
280 | string lastName = args[6]; | ||
281 | |||
282 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
283 | { | ||
284 | if (sp.Firstname == firstName && sp.Lastname == lastName) | ||
285 | { | ||
286 | MainConsole.Instance.OutputFormat( | ||
287 | "Data debug for {0} ({1}) set to {2} in {3}", | ||
288 | sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name); | ||
289 | |||
290 | ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level; | ||
291 | } | ||
292 | }); | ||
293 | } | ||
294 | |||
295 | private void HandleThrottleCommand(string module, string[] args) | ||
296 | { | ||
297 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
298 | return; | ||
299 | |||
300 | bool all = args.Length == 5; | ||
301 | bool one = args.Length == 7; | ||
302 | |||
303 | if (!all && !one) | ||
304 | { | ||
305 | MainConsole.Instance.OutputFormat( | ||
306 | "Usage: debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]"); | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | int level; | ||
311 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level)) | ||
312 | return; | ||
313 | |||
314 | string firstName = null; | ||
315 | string lastName = null; | ||
316 | |||
317 | if (one) | ||
318 | { | ||
319 | firstName = args[5]; | ||
320 | lastName = args[6]; | ||
321 | } | ||
322 | |||
323 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
324 | { | ||
325 | if (all || (sp.Firstname == firstName && sp.Lastname == lastName)) | ||
326 | { | ||
327 | MainConsole.Instance.OutputFormat( | ||
328 | "Throttle log level for {0} ({1}) set to {2} in {3}", | ||
329 | sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name); | ||
330 | |||
331 | ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level; | ||
332 | } | ||
333 | }); | ||
334 | } | ||
335 | |||
336 | private void HandleThrottleSetCommand(string module, string[] args) | ||
337 | { | ||
338 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
339 | return; | ||
340 | |||
341 | bool all = args.Length == 6; | ||
342 | bool one = args.Length == 8; | ||
343 | |||
344 | if (!all && !one) | ||
345 | { | ||
346 | MainConsole.Instance.OutputFormat( | ||
347 | "Usage: debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]"); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | string param = args[4]; | ||
352 | string rawValue = args[5]; | ||
353 | |||
354 | string firstName = null; | ||
355 | string lastName = null; | ||
356 | |||
357 | if (one) | ||
358 | { | ||
359 | firstName = args[6]; | ||
360 | lastName = args[7]; | ||
361 | } | ||
362 | |||
363 | if (param == "adaptive") | ||
364 | { | ||
365 | bool newValue; | ||
366 | if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newValue)) | ||
367 | return; | ||
368 | |||
369 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
370 | { | ||
371 | if (all || (sp.Firstname == firstName && sp.Lastname == lastName)) | ||
372 | { | ||
373 | MainConsole.Instance.OutputFormat( | ||
374 | "Setting param {0} to {1} for {2} ({3}) in {4}", | ||
375 | param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name); | ||
376 | |||
377 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
378 | udpClient.FlowThrottle.AdaptiveEnabled = newValue; | ||
379 | // udpClient.FlowThrottle.MaxDripRate = 0; | ||
380 | // udpClient.FlowThrottle.AdjustedDripRate = 0; | ||
381 | } | ||
382 | }); | ||
383 | } | ||
384 | else if (param == "request") | ||
385 | { | ||
386 | int newValue; | ||
387 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue)) | ||
388 | return; | ||
389 | |||
390 | int newCurrentThrottleKbps = newValue * 1000 / 8; | ||
391 | |||
392 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
393 | { | ||
394 | if (all || (sp.Firstname == firstName && sp.Lastname == lastName)) | ||
395 | { | ||
396 | MainConsole.Instance.OutputFormat( | ||
397 | "Setting param {0} to {1} for {2} ({3}) in {4}", | ||
398 | param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name); | ||
399 | |||
400 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
401 | udpClient.FlowThrottle.RequestedDripRate = newCurrentThrottleKbps; | ||
402 | } | ||
403 | }); | ||
404 | } | ||
405 | else if (param == "max") | ||
406 | { | ||
407 | int newValue; | ||
408 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue)) | ||
409 | return; | ||
410 | |||
411 | int newThrottleMaxKbps = newValue * 1000 / 8; | ||
412 | |||
413 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
414 | { | ||
415 | if (all || (sp.Firstname == firstName && sp.Lastname == lastName)) | ||
416 | { | ||
417 | MainConsole.Instance.OutputFormat( | ||
418 | "Setting param {0} to {1} for {2} ({3}) in {4}", | ||
419 | param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name); | ||
420 | |||
421 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
422 | udpClient.FlowThrottle.MaxDripRate = newThrottleMaxKbps; | ||
423 | } | ||
424 | }); | ||
425 | } | ||
426 | } | ||
427 | |||
428 | private void HandleThrottleGetCommand(string module, string[] args) | ||
429 | { | ||
430 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
431 | return; | ||
432 | |||
433 | bool all = args.Length == 4; | ||
434 | bool one = args.Length == 6; | ||
435 | |||
436 | if (!all && !one) | ||
437 | { | ||
438 | MainConsole.Instance.OutputFormat( | ||
439 | "Usage: debug lludp throttles get [<avatar-first-name> <avatar-last-name>]"); | ||
440 | return; | ||
441 | } | ||
442 | |||
443 | string firstName = null; | ||
444 | string lastName = null; | ||
445 | |||
446 | if (one) | ||
447 | { | ||
448 | firstName = args[4]; | ||
449 | lastName = args[5]; | ||
450 | } | ||
451 | |||
452 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
453 | { | ||
454 | if (all || (sp.Firstname == firstName && sp.Lastname == lastName)) | ||
455 | { | ||
456 | m_console.OutputFormat( | ||
457 | "Status for {0} ({1}) in {2}", | ||
458 | sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name); | ||
459 | |||
460 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
461 | |||
462 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
463 | cdl.AddRow("adaptive", udpClient.FlowThrottle.AdaptiveEnabled); | ||
464 | cdl.AddRow("current", string.Format("{0} kbps", udpClient.FlowThrottle.DripRate * 8 / 1000)); | ||
465 | cdl.AddRow("request", string.Format("{0} kbps", udpClient.FlowThrottle.RequestedDripRate * 8 / 1000)); | ||
466 | cdl.AddRow("max", string.Format("{0} kbps", udpClient.FlowThrottle.MaxDripRate * 8 / 1000)); | ||
467 | |||
468 | m_console.Output(cdl.ToString()); | ||
469 | } | ||
470 | }); | ||
471 | } | ||
472 | |||
473 | private void HandleGetCommand(string module, string[] args) | ||
474 | { | ||
475 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
476 | return; | ||
477 | |||
478 | m_console.OutputFormat("Debug settings for {0}", m_udpServer.Scene.Name); | ||
479 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
480 | |||
481 | long maxSceneDripRate = m_udpServer.Throttle.MaxDripRate; | ||
482 | cdl.AddRow( | ||
483 | "max-scene-throttle", | ||
484 | maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset"); | ||
485 | |||
486 | int maxClientDripRate = m_udpServer.ThrottleRates.Total; | ||
487 | cdl.AddRow( | ||
488 | "max-new-client-throttle", | ||
489 | maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset"); | ||
490 | |||
491 | m_console.Output(cdl.ToString()); | ||
492 | } | ||
493 | |||
494 | private void HandleSetCommand(string module, string[] args) | ||
495 | { | ||
496 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
497 | return; | ||
498 | |||
499 | if (args.Length != 5) | ||
500 | { | ||
501 | MainConsole.Instance.OutputFormat("Usage: debug lludp set <param> <value>"); | ||
502 | return; | ||
503 | } | ||
504 | |||
505 | string param = args[3]; | ||
506 | string rawValue = args[4]; | ||
507 | |||
508 | int newValue; | ||
509 | |||
510 | if (param == "max-scene-throttle") | ||
511 | { | ||
512 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue)) | ||
513 | return; | ||
514 | |||
515 | m_udpServer.Throttle.MaxDripRate = newValue * 1000 / 8; | ||
516 | } | ||
517 | else if (param == "max-new-client-throttle") | ||
518 | { | ||
519 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue)) | ||
520 | return; | ||
521 | |||
522 | m_udpServer.ThrottleRates.Total = newValue * 1000 / 8; | ||
523 | } | ||
524 | else | ||
525 | { | ||
526 | return; | ||
527 | } | ||
528 | |||
529 | m_console.OutputFormat("{0} set to {1} in {2}", param, rawValue, m_udpServer.Scene.Name); | ||
530 | } | ||
531 | |||
532 | private void HandlePacketCommand(string module, string[] args) | ||
533 | { | ||
534 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
535 | return; | ||
536 | |||
537 | bool setAsDefaultLevel = false; | ||
538 | bool setAll = false; | ||
539 | OptionSet optionSet = new OptionSet() | ||
540 | .Add("default", o => setAsDefaultLevel = (o != null)) | ||
541 | .Add("all", o => setAll = (o != null)); | ||
542 | List<string> filteredArgs = optionSet.Parse(args); | ||
543 | |||
544 | string name = null; | ||
545 | |||
546 | if (filteredArgs.Count == 6) | ||
547 | { | ||
548 | if (!(setAsDefaultLevel || setAll)) | ||
549 | { | ||
550 | name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]); | ||
551 | } | ||
552 | else | ||
553 | { | ||
554 | MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level"); | ||
555 | return; | ||
556 | } | ||
557 | } | ||
558 | |||
559 | if (filteredArgs.Count > 3) | ||
560 | { | ||
561 | int newDebug; | ||
562 | if (int.TryParse(filteredArgs[3], out newDebug)) | ||
563 | { | ||
564 | if (setAsDefaultLevel || setAll) | ||
565 | { | ||
566 | m_udpServer.DefaultClientPacketDebugLevel = newDebug; | ||
567 | |||
568 | MainConsole.Instance.OutputFormat( | ||
569 | "Packet debug for {0} clients set to {1} in {2}", | ||
570 | (setAll ? "all" : "future"), m_udpServer.DefaultClientPacketDebugLevel, m_udpServer.Scene.Name); | ||
571 | |||
572 | if (setAll) | ||
573 | { | ||
574 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
575 | { | ||
576 | MainConsole.Instance.OutputFormat( | ||
577 | "Packet debug for {0} ({1}) set to {2} in {3}", | ||
578 | sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name); | ||
579 | |||
580 | sp.ControllingClient.DebugPacketLevel = newDebug; | ||
581 | }); | ||
582 | } | ||
583 | } | ||
584 | else | ||
585 | { | ||
586 | m_udpServer.Scene.ForEachScenePresence(sp => | ||
587 | { | ||
588 | if (name == null || sp.Name == name) | ||
589 | { | ||
590 | MainConsole.Instance.OutputFormat( | ||
591 | "Packet debug for {0} ({1}) set to {2} in {3}", | ||
592 | sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name); | ||
593 | |||
594 | sp.ControllingClient.DebugPacketLevel = newDebug; | ||
595 | } | ||
596 | }); | ||
597 | } | ||
598 | } | ||
599 | else | ||
600 | { | ||
601 | MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]"); | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | |||
606 | private void HandleDropCommand(string module, string[] args) | ||
607 | { | ||
608 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
609 | return; | ||
610 | |||
611 | if (args.Length != 6) | ||
612 | { | ||
613 | MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>"); | ||
614 | return; | ||
615 | } | ||
616 | |||
617 | string direction = args[3]; | ||
618 | string subCommand = args[4]; | ||
619 | string packetName = args[5]; | ||
620 | |||
621 | if (subCommand == "add") | ||
622 | { | ||
623 | MainConsole.Instance.OutputFormat( | ||
624 | "Adding packet {0} to {1} drop list for all connections in {2}", | ||
625 | direction, packetName, m_udpServer.Scene.Name); | ||
626 | |||
627 | m_udpServer.Scene.ForEachScenePresence( | ||
628 | sp => | ||
629 | { | ||
630 | LLClientView llcv = (LLClientView)sp.ControllingClient; | ||
631 | |||
632 | if (direction == "in") | ||
633 | llcv.AddInPacketToDropSet(packetName); | ||
634 | else if (direction == "out") | ||
635 | llcv.AddOutPacketToDropSet(packetName); | ||
636 | } | ||
637 | ); | ||
638 | } | ||
639 | else if (subCommand == "remove") | ||
640 | { | ||
641 | MainConsole.Instance.OutputFormat( | ||
642 | "Removing packet {0} from {1} drop list for all connections in {2}", | ||
643 | direction, packetName, m_udpServer.Scene.Name); | ||
644 | |||
645 | m_udpServer.Scene.ForEachScenePresence( | ||
646 | sp => | ||
647 | { | ||
648 | LLClientView llcv = (LLClientView)sp.ControllingClient; | ||
649 | |||
650 | if (direction == "in") | ||
651 | llcv.RemoveInPacketFromDropSet(packetName); | ||
652 | else if (direction == "out") | ||
653 | llcv.RemoveOutPacketFromDropSet(packetName); | ||
654 | } | ||
655 | ); | ||
656 | } | ||
657 | } | ||
658 | |||
659 | private void HandleStartCommand(string module, string[] args) | ||
660 | { | ||
661 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
662 | return; | ||
663 | |||
664 | if (args.Length != 4) | ||
665 | { | ||
666 | MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>"); | ||
667 | return; | ||
668 | } | ||
669 | |||
670 | string subCommand = args[3]; | ||
671 | |||
672 | if (subCommand == "in" || subCommand == "all") | ||
673 | m_udpServer.StartInbound(); | ||
674 | |||
675 | if (subCommand == "out" || subCommand == "all") | ||
676 | m_udpServer.StartOutbound(); | ||
677 | } | ||
678 | |||
679 | private void HandleStopCommand(string module, string[] args) | ||
680 | { | ||
681 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
682 | return; | ||
683 | |||
684 | if (args.Length != 4) | ||
685 | { | ||
686 | MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>"); | ||
687 | return; | ||
688 | } | ||
689 | |||
690 | string subCommand = args[3]; | ||
691 | |||
692 | if (subCommand == "in" || subCommand == "all") | ||
693 | m_udpServer.StopInbound(); | ||
694 | |||
695 | if (subCommand == "out" || subCommand == "all") | ||
696 | m_udpServer.StopOutbound(); | ||
697 | } | ||
698 | |||
699 | private void HandlePoolCommand(string module, string[] args) | ||
700 | { | ||
701 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
702 | return; | ||
703 | |||
704 | if (args.Length != 4) | ||
705 | { | ||
706 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
707 | return; | ||
708 | } | ||
709 | |||
710 | string enabled = args[3]; | ||
711 | |||
712 | if (enabled == "on") | ||
713 | { | ||
714 | if (m_udpServer.EnablePools()) | ||
715 | { | ||
716 | m_udpServer.EnablePoolStats(); | ||
717 | MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name); | ||
718 | } | ||
719 | } | ||
720 | else if (enabled == "off") | ||
721 | { | ||
722 | if (m_udpServer.DisablePools()) | ||
723 | { | ||
724 | m_udpServer.DisablePoolStats(); | ||
725 | MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name); | ||
726 | } | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
731 | } | ||
732 | } | ||
733 | |||
734 | private void HandleAgentUpdateCommand(string module, string[] args) | ||
735 | { | ||
736 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
737 | return; | ||
738 | |||
739 | m_udpServer.DiscardInboundAgentUpdates = !m_udpServer.DiscardInboundAgentUpdates; | ||
740 | |||
741 | MainConsole.Instance.OutputFormat( | ||
742 | "Discard AgentUpdates now {0} for {1}", m_udpServer.DiscardInboundAgentUpdates, m_udpServer.Scene.Name); | ||
743 | } | ||
744 | |||
745 | private void HandleStatusCommand(string module, string[] args) | ||
746 | { | ||
747 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
748 | return; | ||
749 | |||
750 | MainConsole.Instance.OutputFormat( | ||
751 | "IN LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningInbound ? "enabled" : "disabled"); | ||
752 | |||
753 | MainConsole.Instance.OutputFormat( | ||
754 | "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled"); | ||
755 | |||
756 | MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off"); | ||
757 | |||
758 | MainConsole.Instance.OutputFormat( | ||
759 | "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel); | ||
760 | } | ||
761 | } | ||
762 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 88494be..94300f8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -135,7 +135,7 @@ namespace OpenMetaverse | |||
135 | /// manner (not throwing an exception when the remote side resets the | 135 | /// manner (not throwing an exception when the remote side resets the |
136 | /// connection). This call is ignored on Mono where the flag is not | 136 | /// connection). This call is ignored on Mono where the flag is not |
137 | /// necessary</remarks> | 137 | /// necessary</remarks> |
138 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) | 138 | public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
139 | { | 139 | { |
140 | m_asyncPacketHandling = asyncPacketHandling; | 140 | m_asyncPacketHandling = asyncPacketHandling; |
141 | 141 | ||
@@ -168,6 +168,12 @@ namespace OpenMetaverse | |||
168 | m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); | 168 | m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); |
169 | } | 169 | } |
170 | 170 | ||
171 | // On at least Mono 3.2.8, multiple UDP sockets can bind to the same port by default. At the moment | ||
172 | // we never want two regions to listen on the same port as they cannot demultiplex each other's messages, | ||
173 | // leading to a confusing bug. | ||
174 | // By default, Windows does not allow two sockets to bind to the same port. | ||
175 | m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); | ||
176 | |||
171 | if (recvBufferSize != 0) | 177 | if (recvBufferSize != 0) |
172 | m_udpSocket.ReceiveBufferSize = recvBufferSize; | 178 | m_udpSocket.ReceiveBufferSize = recvBufferSize; |
173 | 179 | ||
@@ -185,14 +191,14 @@ namespace OpenMetaverse | |||
185 | /// <summary> | 191 | /// <summary> |
186 | /// Start outbound UDP packet handling. | 192 | /// Start outbound UDP packet handling. |
187 | /// </summary> | 193 | /// </summary> |
188 | public void StartOutbound() | 194 | public virtual void StartOutbound() |
189 | { | 195 | { |
190 | m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop"); | 196 | m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop"); |
191 | 197 | ||
192 | IsRunningOutbound = true; | 198 | IsRunningOutbound = true; |
193 | } | 199 | } |
194 | 200 | ||
195 | public void StopInbound() | 201 | public virtual void StopInbound() |
196 | { | 202 | { |
197 | if (IsRunningInbound) | 203 | if (IsRunningInbound) |
198 | { | 204 | { |
@@ -203,14 +209,14 @@ namespace OpenMetaverse | |||
203 | } | 209 | } |
204 | } | 210 | } |
205 | 211 | ||
206 | public void StopOutbound() | 212 | public virtual void StopOutbound() |
207 | { | 213 | { |
208 | m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop"); | 214 | m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop"); |
209 | 215 | ||
210 | IsRunningOutbound = false; | 216 | IsRunningOutbound = false; |
211 | } | 217 | } |
212 | 218 | ||
213 | protected virtual bool EnablePools() | 219 | public virtual bool EnablePools() |
214 | { | 220 | { |
215 | if (!UsePools) | 221 | if (!UsePools) |
216 | { | 222 | { |
@@ -224,7 +230,7 @@ namespace OpenMetaverse | |||
224 | return false; | 230 | return false; |
225 | } | 231 | } |
226 | 232 | ||
227 | protected virtual bool DisablePools() | 233 | public virtual bool DisablePools() |
228 | { | 234 | { |
229 | if (UsePools) | 235 | if (UsePools) |
230 | { | 236 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs index 069c9c8..1e915c3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingQueueRefillEngine.cs | |||
@@ -124,7 +124,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
124 | 124 | ||
125 | StatsManager.RegisterStat(m_oqreRequestsWaitingStat); | 125 | StatsManager.RegisterStat(m_oqreRequestsWaitingStat); |
126 | 126 | ||
127 | Watchdog.StartThread( | 127 | WorkManager.StartThread( |
128 | ProcessRequests, | 128 | ProcessRequests, |
129 | String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name), | 129 | String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name), |
130 | ThreadPriority.Normal, | 130 | ThreadPriority.Normal, |
@@ -217,6 +217,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
217 | 217 | ||
218 | private void ProcessRequests() | 218 | private void ProcessRequests() |
219 | { | 219 | { |
220 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
221 | |||
220 | try | 222 | try |
221 | { | 223 | { |
222 | while (IsRunning || m_requestQueue.Count > 0) | 224 | while (IsRunning || m_requestQueue.Count > 0) |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index e9aeffe..a935dd2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs | |||
@@ -36,7 +36,6 @@ using OpenSim.Framework; | |||
36 | using OpenSim.Framework.Monitoring; | 36 | using OpenSim.Framework.Monitoring; |
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | ||
40 | 39 | ||
41 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | 40 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests |
42 | { | 41 | { |
@@ -47,7 +46,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
47 | public class BasicCircuitTests : OpenSimTestCase | 46 | public class BasicCircuitTests : OpenSimTestCase |
48 | { | 47 | { |
49 | private Scene m_scene; | 48 | private Scene m_scene; |
50 | private TestLLUDPServer m_udpServer; | ||
51 | 49 | ||
52 | [TestFixtureSetUp] | 50 | [TestFixtureSetUp] |
53 | public void FixtureInit() | 51 | public void FixtureInit() |
@@ -73,72 +71,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
73 | StatsManager.SimExtraStats = new SimExtraStatsCollector(); | 71 | StatsManager.SimExtraStats = new SimExtraStatsCollector(); |
74 | } | 72 | } |
75 | 73 | ||
76 | /// <summary> | 74 | // /// <summary> |
77 | /// Build an object name packet for test purposes | 75 | // /// Build an object name packet for test purposes |
78 | /// </summary> | 76 | // /// </summary> |
79 | /// <param name="objectLocalId"></param> | 77 | // /// <param name="objectLocalId"></param> |
80 | /// <param name="objectName"></param> | 78 | // /// <param name="objectName"></param> |
81 | private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) | 79 | // private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) |
82 | { | 80 | // { |
83 | ObjectNamePacket onp = new ObjectNamePacket(); | 81 | // ObjectNamePacket onp = new ObjectNamePacket(); |
84 | ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock(); | 82 | // ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock(); |
85 | odb.LocalID = objectLocalId; | 83 | // odb.LocalID = objectLocalId; |
86 | odb.Name = Utils.StringToBytes(objectName); | 84 | // odb.Name = Utils.StringToBytes(objectName); |
87 | onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb }; | 85 | // onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb }; |
88 | onp.Header.Zerocoded = false; | 86 | // onp.Header.Zerocoded = false; |
89 | 87 | // | |
90 | return onp; | 88 | // return onp; |
91 | } | 89 | // } |
92 | 90 | // | |
93 | private void AddUdpServer() | ||
94 | { | ||
95 | AddUdpServer(new IniConfigSource()); | ||
96 | } | ||
97 | |||
98 | private void AddUdpServer(IniConfigSource configSource) | ||
99 | { | ||
100 | uint port = 0; | ||
101 | AgentCircuitManager acm = m_scene.AuthenticateHandler; | ||
102 | |||
103 | m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm); | ||
104 | m_udpServer.AddScene(m_scene); | ||
105 | } | ||
106 | |||
107 | /// <summary> | ||
108 | /// Used by tests that aren't testing this stage. | ||
109 | /// </summary> | ||
110 | private ScenePresence AddClient() | ||
111 | { | ||
112 | UUID myAgentUuid = TestHelpers.ParseTail(0x1); | ||
113 | UUID mySessionUuid = TestHelpers.ParseTail(0x2); | ||
114 | uint myCircuitCode = 123456; | ||
115 | IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); | ||
116 | |||
117 | UseCircuitCodePacket uccp = new UseCircuitCodePacket(); | ||
118 | |||
119 | UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock | ||
120 | = new UseCircuitCodePacket.CircuitCodeBlock(); | ||
121 | uccpCcBlock.Code = myCircuitCode; | ||
122 | uccpCcBlock.ID = myAgentUuid; | ||
123 | uccpCcBlock.SessionID = mySessionUuid; | ||
124 | uccp.CircuitCode = uccpCcBlock; | ||
125 | |||
126 | byte[] uccpBytes = uccp.ToBytes(); | ||
127 | UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length); | ||
128 | upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. | ||
129 | Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); | ||
130 | |||
131 | AgentCircuitData acd = new AgentCircuitData(); | ||
132 | acd.AgentID = myAgentUuid; | ||
133 | acd.SessionID = mySessionUuid; | ||
134 | |||
135 | m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); | ||
136 | |||
137 | m_udpServer.PacketReceived(upb); | ||
138 | |||
139 | return m_scene.GetScenePresence(myAgentUuid); | ||
140 | } | ||
141 | |||
142 | /// <summary> | 91 | /// <summary> |
143 | /// Test adding a client to the stack | 92 | /// Test adding a client to the stack |
144 | /// </summary> | 93 | /// </summary> |
@@ -148,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
148 | TestHelpers.InMethod(); | 97 | TestHelpers.InMethod(); |
149 | // TestHelpers.EnableLogging(); | 98 | // TestHelpers.EnableLogging(); |
150 | 99 | ||
151 | AddUdpServer(); | 100 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene); |
152 | 101 | ||
153 | UUID myAgentUuid = TestHelpers.ParseTail(0x1); | 102 | UUID myAgentUuid = TestHelpers.ParseTail(0x1); |
154 | UUID mySessionUuid = TestHelpers.ParseTail(0x2); | 103 | UUID mySessionUuid = TestHelpers.ParseTail(0x2); |
@@ -169,7 +118,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
169 | upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. | 118 | upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. |
170 | Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); | 119 | Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); |
171 | 120 | ||
172 | m_udpServer.PacketReceived(upb); | 121 | udpServer.PacketReceived(upb); |
173 | 122 | ||
174 | // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet | 123 | // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet |
175 | Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null); | 124 | Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null); |
@@ -180,15 +129,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
180 | 129 | ||
181 | m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); | 130 | m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); |
182 | 131 | ||
183 | m_udpServer.PacketReceived(upb); | 132 | udpServer.PacketReceived(upb); |
184 | 133 | ||
185 | // Should succeed now | 134 | // Should succeed now |
186 | ScenePresence sp = m_scene.GetScenePresence(myAgentUuid); | 135 | ScenePresence sp = m_scene.GetScenePresence(myAgentUuid); |
187 | Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); | 136 | Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); |
188 | 137 | ||
189 | Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1)); | 138 | Assert.That(udpServer.PacketsSent.Count, Is.EqualTo(1)); |
190 | 139 | ||
191 | Packet packet = m_udpServer.PacketsSent[0]; | 140 | Packet packet = udpServer.PacketsSent[0]; |
192 | Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket))); | 141 | Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket))); |
193 | 142 | ||
194 | PacketAckPacket ackPacket = packet as PacketAckPacket; | 143 | PacketAckPacket ackPacket = packet as PacketAckPacket; |
@@ -200,15 +149,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
200 | public void TestLogoutClientDueToAck() | 149 | public void TestLogoutClientDueToAck() |
201 | { | 150 | { |
202 | TestHelpers.InMethod(); | 151 | TestHelpers.InMethod(); |
203 | TestHelpers.EnableLogging(); | 152 | // TestHelpers.EnableLogging(); |
204 | 153 | ||
205 | IniConfigSource ics = new IniConfigSource(); | 154 | IniConfigSource ics = new IniConfigSource(); |
206 | IConfig config = ics.AddConfig("ClientStack.LindenUDP"); | 155 | IConfig config = ics.AddConfig("ClientStack.LindenUDP"); |
207 | config.Set("AckTimeout", -1); | 156 | config.Set("AckTimeout", -1); |
208 | AddUdpServer(ics); | 157 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene, ics); |
158 | |||
159 | ScenePresence sp | ||
160 | = ClientStackHelpers.AddChildClient( | ||
161 | m_scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456); | ||
209 | 162 | ||
210 | ScenePresence sp = AddClient(); | 163 | udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false); |
211 | m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false); | ||
212 | 164 | ||
213 | ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); | 165 | ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); |
214 | Assert.That(spAfterAckTimeout, Is.Null); | 166 | Assert.That(spAfterAckTimeout, Is.Null); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 575e54c..6c57e6d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs | |||
@@ -39,7 +39,6 @@ using OpenSim.Framework; | |||
39 | using OpenSim.Region.CoreModules.Agent.TextureSender; | 39 | using OpenSim.Region.CoreModules.Agent.TextureSender; |
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | 43 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests |
45 | { | 44 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs deleted file mode 100644 index 39d1875..0000000 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System.Net; | ||
29 | using OpenMetaverse; | ||
30 | using OpenSim.Framework; | ||
31 | using OpenSim.Region.Framework.Scenes; | ||
32 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
33 | |||
34 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | ||
35 | { | ||
36 | /// <summary> | ||
37 | /// Mock scene for unit tests | ||
38 | /// </summary> | ||
39 | public class MockScene : SceneBase | ||
40 | { | ||
41 | public int ObjectNameCallsReceived | ||
42 | { | ||
43 | get { return m_objectNameCallsReceived; } | ||
44 | } | ||
45 | protected int m_objectNameCallsReceived; | ||
46 | |||
47 | public MockScene() : base(new RegionInfo(1000, 1000, null, null)) | ||
48 | { | ||
49 | m_regStatus = RegionStatus.Up; | ||
50 | } | ||
51 | |||
52 | public override bool Update(int frames) { return true; } | ||
53 | public override void LoadWorldMap() {} | ||
54 | |||
55 | public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type) | ||
56 | { | ||
57 | client.OnObjectName += RecordObjectNameCall; | ||
58 | |||
59 | // FIXME | ||
60 | return null; | ||
61 | } | ||
62 | |||
63 | public override bool CloseAgent(UUID agentID, bool force) { return true; } | ||
64 | |||
65 | public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; } | ||
66 | |||
67 | public override void OtherRegionUp(GridRegion otherRegion) { } | ||
68 | |||
69 | public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; } | ||
70 | |||
71 | /// <summary> | ||
72 | /// Doesn't really matter what the call is - we're using this to test that a packet has actually been received | ||
73 | /// </summary> | ||
74 | protected void RecordObjectNameCall(IClientAPI remoteClient, uint localID, string message) | ||
75 | { | ||
76 | m_objectNameCallsReceived++; | ||
77 | } | ||
78 | } | ||
79 | } | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs index 5f73a94..92f1fc3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs | |||
@@ -30,7 +30,6 @@ using NUnit.Framework; | |||
30 | using OpenMetaverse; | 30 | using OpenMetaverse; |
31 | using OpenMetaverse.Packets; | 31 | using OpenMetaverse.Packets; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Tests.Common.Mock; | ||
34 | using OpenSim.Tests.Common; | 33 | using OpenSim.Tests.Common; |
35 | 34 | ||
36 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | 35 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs new file mode 100644 index 0000000..0560b9b --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs | |||
@@ -0,0 +1,425 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using Nini.Config; | ||
30 | using NUnit.Framework; | ||
31 | using OpenMetaverse.Packets; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenSim.Tests.Common; | ||
35 | |||
36 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | ||
37 | { | ||
38 | [TestFixture] | ||
39 | public class ThrottleTests : OpenSimTestCase | ||
40 | { | ||
41 | [TestFixtureSetUp] | ||
42 | public void FixtureInit() | ||
43 | { | ||
44 | // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. | ||
45 | Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; | ||
46 | } | ||
47 | |||
48 | [TestFixtureTearDown] | ||
49 | public void TearDown() | ||
50 | { | ||
51 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
52 | // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression | ||
53 | // tests really shouldn't). | ||
54 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
55 | } | ||
56 | |||
57 | [Test] | ||
58 | public void TestSetRequestDripRate() | ||
59 | { | ||
60 | TestHelpers.InMethod(); | ||
61 | |||
62 | TokenBucket tb = new TokenBucket("tb", null, 5000, 0); | ||
63 | AssertRates(tb, 5000, 0, 5000, 0); | ||
64 | |||
65 | tb.RequestedDripRate = 4000; | ||
66 | AssertRates(tb, 4000, 0, 4000, 0); | ||
67 | |||
68 | tb.RequestedDripRate = 6000; | ||
69 | AssertRates(tb, 6000, 0, 6000, 0); | ||
70 | } | ||
71 | |||
72 | [Test] | ||
73 | public void TestSetRequestDripRateWithMax() | ||
74 | { | ||
75 | TestHelpers.InMethod(); | ||
76 | |||
77 | TokenBucket tb = new TokenBucket("tb", null, 5000, 10000); | ||
78 | AssertRates(tb, 5000, 0, 5000, 10000); | ||
79 | |||
80 | tb.RequestedDripRate = 4000; | ||
81 | AssertRates(tb, 4000, 0, 4000, 10000); | ||
82 | |||
83 | tb.RequestedDripRate = 6000; | ||
84 | AssertRates(tb, 6000, 0, 6000, 10000); | ||
85 | |||
86 | tb.RequestedDripRate = 12000; | ||
87 | AssertRates(tb, 10000, 0, 10000, 10000); | ||
88 | } | ||
89 | |||
90 | [Test] | ||
91 | public void TestSetRequestDripRateWithChildren() | ||
92 | { | ||
93 | TestHelpers.InMethod(); | ||
94 | |||
95 | TokenBucket tbParent = new TokenBucket("tbParent", null, 0, 0); | ||
96 | TokenBucket tbChild1 = new TokenBucket("tbChild1", tbParent, 3000, 0); | ||
97 | TokenBucket tbChild2 = new TokenBucket("tbChild2", tbParent, 5000, 0); | ||
98 | |||
99 | AssertRates(tbParent, 8000, 8000, 8000, 0); | ||
100 | AssertRates(tbChild1, 3000, 0, 3000, 0); | ||
101 | AssertRates(tbChild2, 5000, 0, 5000, 0); | ||
102 | |||
103 | // Test: Setting a parent request greater than total children requests. | ||
104 | tbParent.RequestedDripRate = 10000; | ||
105 | |||
106 | AssertRates(tbParent, 10000, 8000, 8000, 0); | ||
107 | AssertRates(tbChild1, 3000, 0, 3000, 0); | ||
108 | AssertRates(tbChild2, 5000, 0, 5000, 0); | ||
109 | |||
110 | // Test: Setting a parent request lower than total children requests. | ||
111 | tbParent.RequestedDripRate = 6000; | ||
112 | |||
113 | AssertRates(tbParent, 6000, 8000, 6000, 0); | ||
114 | AssertRates(tbChild1, 3000, 0, 6000 / 8 * 3, 0); | ||
115 | AssertRates(tbChild2, 5000, 0, 6000 / 8 * 5, 0); | ||
116 | } | ||
117 | |||
118 | private void AssertRates( | ||
119 | TokenBucket tb, double requestedDripRate, double totalDripRequest, double dripRate, double maxDripRate) | ||
120 | { | ||
121 | Assert.AreEqual((int)requestedDripRate, tb.RequestedDripRate, "Requested drip rate"); | ||
122 | Assert.AreEqual((int)totalDripRequest, tb.TotalDripRequest, "Total drip request"); | ||
123 | Assert.AreEqual((int)dripRate, tb.DripRate, "Drip rate"); | ||
124 | Assert.AreEqual((int)maxDripRate, tb.MaxDripRate, "Max drip rate"); | ||
125 | } | ||
126 | |||
127 | [Test] | ||
128 | public void TestClientThrottleSetNoLimit() | ||
129 | { | ||
130 | TestHelpers.InMethod(); | ||
131 | // TestHelpers.EnableLogging(); | ||
132 | |||
133 | Scene scene = new SceneHelpers().SetupScene(); | ||
134 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene); | ||
135 | |||
136 | ScenePresence sp | ||
137 | = ClientStackHelpers.AddChildClient( | ||
138 | scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456); | ||
139 | |||
140 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
141 | |||
142 | udpServer.Throttle.DebugLevel = 1; | ||
143 | udpClient.ThrottleDebugLevel = 1; | ||
144 | |||
145 | int resendBytes = 1000; | ||
146 | int landBytes = 2000; | ||
147 | int windBytes = 3000; | ||
148 | int cloudBytes = 4000; | ||
149 | int taskBytes = 5000; | ||
150 | int textureBytes = 6000; | ||
151 | int assetBytes = 7000; | ||
152 | |||
153 | SetThrottles( | ||
154 | udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
155 | |||
156 | // We expect this to be lower because of the minimum bound set by MTU | ||
157 | int totalBytes = LLUDPServer.MTU + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes; | ||
158 | |||
159 | AssertThrottles( | ||
160 | udpClient, | ||
161 | LLUDPServer.MTU, landBytes, windBytes, cloudBytes, taskBytes, | ||
162 | textureBytes, assetBytes, totalBytes, 0, 0); | ||
163 | } | ||
164 | |||
165 | [Test] | ||
166 | public void TestClientThrottleAdaptiveNoLimit() | ||
167 | { | ||
168 | TestHelpers.InMethod(); | ||
169 | // TestHelpers.EnableLogging(); | ||
170 | |||
171 | Scene scene = new SceneHelpers().SetupScene(); | ||
172 | |||
173 | IniConfigSource ics = new IniConfigSource(); | ||
174 | IConfig config = ics.AddConfig("ClientStack.LindenUDP"); | ||
175 | config.Set("enable_adaptive_throttles", true); | ||
176 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene, ics); | ||
177 | |||
178 | ScenePresence sp | ||
179 | = ClientStackHelpers.AddChildClient( | ||
180 | scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456); | ||
181 | |||
182 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
183 | |||
184 | udpServer.Throttle.DebugLevel = 1; | ||
185 | udpClient.ThrottleDebugLevel = 1; | ||
186 | |||
187 | // Total is 280000 | ||
188 | int resendBytes = 10000; | ||
189 | int landBytes = 20000; | ||
190 | int windBytes = 30000; | ||
191 | int cloudBytes = 40000; | ||
192 | int taskBytes = 50000; | ||
193 | int textureBytes = 60000; | ||
194 | int assetBytes = 70000; | ||
195 | int totalBytes = resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes; | ||
196 | |||
197 | SetThrottles( | ||
198 | udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
199 | |||
200 | // Ratio of current adaptive drip rate to requested bytes | ||
201 | // XXX: Should hard code this as below so we don't rely on values given by tested code to construct | ||
202 | // expected values. | ||
203 | double commitRatio = (double)udpClient.FlowThrottle.AdjustedDripRate / udpClient.FlowThrottle.TargetDripRate; | ||
204 | |||
205 | AssertThrottles( | ||
206 | udpClient, | ||
207 | LLUDPServer.MTU, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio, | ||
208 | textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0); | ||
209 | |||
210 | // Test an increase in target throttle | ||
211 | udpClient.FlowThrottle.AcknowledgePackets(35000); | ||
212 | commitRatio = 0.2; | ||
213 | |||
214 | AssertThrottles( | ||
215 | udpClient, | ||
216 | resendBytes * commitRatio, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio, | ||
217 | textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0); | ||
218 | |||
219 | // Test a decrease in target throttle | ||
220 | udpClient.FlowThrottle.ExpirePackets(1); | ||
221 | commitRatio = 0.1; | ||
222 | |||
223 | AssertThrottles( | ||
224 | udpClient, | ||
225 | LLUDPServer.MTU, landBytes * commitRatio, windBytes * commitRatio, cloudBytes * commitRatio, taskBytes * commitRatio, | ||
226 | textureBytes * commitRatio, assetBytes * commitRatio, udpClient.FlowThrottle.AdjustedDripRate, totalBytes, 0); | ||
227 | } | ||
228 | |||
229 | /// <summary> | ||
230 | /// Test throttle setttings where max client throttle has been limited server side. | ||
231 | /// </summary> | ||
232 | [Test] | ||
233 | public void TestSingleClientThrottleRegionLimited() | ||
234 | { | ||
235 | TestHelpers.InMethod(); | ||
236 | // TestHelpers.EnableLogging(); | ||
237 | |||
238 | int resendBytes = 6000; | ||
239 | int landBytes = 8000; | ||
240 | int windBytes = 10000; | ||
241 | int cloudBytes = 12000; | ||
242 | int taskBytes = 14000; | ||
243 | int textureBytes = 16000; | ||
244 | int assetBytes = 18000; | ||
245 | int totalBytes | ||
246 | = (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2); | ||
247 | |||
248 | Scene scene = new SceneHelpers().SetupScene(); | ||
249 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene); | ||
250 | udpServer.Throttle.RequestedDripRate = totalBytes; | ||
251 | |||
252 | ScenePresence sp1 | ||
253 | = ClientStackHelpers.AddChildClient( | ||
254 | scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456); | ||
255 | |||
256 | LLUDPClient udpClient1 = ((LLClientView)sp1.ControllingClient).UDPClient; | ||
257 | |||
258 | SetThrottles( | ||
259 | udpClient1, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
260 | |||
261 | AssertThrottles( | ||
262 | udpClient1, | ||
263 | resendBytes / 2, landBytes / 2, windBytes / 2, cloudBytes / 2, taskBytes / 2, | ||
264 | textureBytes / 2, assetBytes / 2, totalBytes, 0, 0); | ||
265 | |||
266 | // Test: Now add another client | ||
267 | ScenePresence sp2 | ||
268 | = ClientStackHelpers.AddChildClient( | ||
269 | scene, udpServer, TestHelpers.ParseTail(0x10), TestHelpers.ParseTail(0x20), 123457); | ||
270 | |||
271 | LLUDPClient udpClient2 = ((LLClientView)sp2.ControllingClient).UDPClient; | ||
272 | // udpClient.ThrottleDebugLevel = 1; | ||
273 | |||
274 | SetThrottles( | ||
275 | udpClient2, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
276 | |||
277 | AssertThrottles( | ||
278 | udpClient1, | ||
279 | resendBytes / 4, landBytes / 4, windBytes / 4, cloudBytes / 4, taskBytes / 4, | ||
280 | textureBytes / 4, assetBytes / 4, totalBytes / 2, 0, 0); | ||
281 | |||
282 | AssertThrottles( | ||
283 | udpClient2, | ||
284 | resendBytes / 4, landBytes / 4, windBytes / 4, cloudBytes / 4, taskBytes / 4, | ||
285 | textureBytes / 4, assetBytes / 4, totalBytes / 2, 0, 0); | ||
286 | } | ||
287 | |||
288 | /// <summary> | ||
289 | /// Test throttle setttings where max client throttle has been limited server side. | ||
290 | /// </summary> | ||
291 | [Test] | ||
292 | public void TestClientThrottlePerClientLimited() | ||
293 | { | ||
294 | TestHelpers.InMethod(); | ||
295 | // TestHelpers.EnableLogging(); | ||
296 | |||
297 | int resendBytes = 4000; | ||
298 | int landBytes = 6000; | ||
299 | int windBytes = 8000; | ||
300 | int cloudBytes = 10000; | ||
301 | int taskBytes = 12000; | ||
302 | int textureBytes = 14000; | ||
303 | int assetBytes = 16000; | ||
304 | int totalBytes | ||
305 | = (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2); | ||
306 | |||
307 | Scene scene = new SceneHelpers().SetupScene(); | ||
308 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene); | ||
309 | udpServer.ThrottleRates.Total = totalBytes; | ||
310 | |||
311 | ScenePresence sp | ||
312 | = ClientStackHelpers.AddChildClient( | ||
313 | scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456); | ||
314 | |||
315 | LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient; | ||
316 | // udpClient.ThrottleDebugLevel = 1; | ||
317 | |||
318 | SetThrottles( | ||
319 | udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
320 | |||
321 | AssertThrottles( | ||
322 | udpClient, | ||
323 | resendBytes / 2, landBytes / 2, windBytes / 2, cloudBytes / 2, taskBytes / 2, | ||
324 | textureBytes / 2, assetBytes / 2, totalBytes, 0, totalBytes); | ||
325 | } | ||
326 | |||
327 | [Test] | ||
328 | public void TestClientThrottlePerClientAndRegionLimited() | ||
329 | { | ||
330 | TestHelpers.InMethod(); | ||
331 | //TestHelpers.EnableLogging(); | ||
332 | |||
333 | int resendBytes = 4000; | ||
334 | int landBytes = 6000; | ||
335 | int windBytes = 8000; | ||
336 | int cloudBytes = 10000; | ||
337 | int taskBytes = 12000; | ||
338 | int textureBytes = 14000; | ||
339 | int assetBytes = 16000; | ||
340 | |||
341 | // current total 70000 | ||
342 | int totalBytes = resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes; | ||
343 | |||
344 | Scene scene = new SceneHelpers().SetupScene(); | ||
345 | TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene); | ||
346 | udpServer.ThrottleRates.Total = (int)(totalBytes * 1.1); | ||
347 | udpServer.Throttle.RequestedDripRate = (int)(totalBytes * 1.5); | ||
348 | |||
349 | ScenePresence sp1 | ||
350 | = ClientStackHelpers.AddChildClient( | ||
351 | scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456); | ||
352 | |||
353 | LLUDPClient udpClient1 = ((LLClientView)sp1.ControllingClient).UDPClient; | ||
354 | udpClient1.ThrottleDebugLevel = 1; | ||
355 | |||
356 | SetThrottles( | ||
357 | udpClient1, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
358 | |||
359 | AssertThrottles( | ||
360 | udpClient1, | ||
361 | resendBytes, landBytes, windBytes, cloudBytes, taskBytes, | ||
362 | textureBytes, assetBytes, totalBytes, 0, totalBytes * 1.1); | ||
363 | |||
364 | // Now add another client | ||
365 | ScenePresence sp2 | ||
366 | = ClientStackHelpers.AddChildClient( | ||
367 | scene, udpServer, TestHelpers.ParseTail(0x10), TestHelpers.ParseTail(0x20), 123457); | ||
368 | |||
369 | LLUDPClient udpClient2 = ((LLClientView)sp2.ControllingClient).UDPClient; | ||
370 | udpClient2.ThrottleDebugLevel = 1; | ||
371 | |||
372 | SetThrottles( | ||
373 | udpClient2, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes); | ||
374 | |||
375 | AssertThrottles( | ||
376 | udpClient1, | ||
377 | resendBytes * 0.75, landBytes * 0.75, windBytes * 0.75, cloudBytes * 0.75, taskBytes * 0.75, | ||
378 | textureBytes * 0.75, assetBytes * 0.75, totalBytes * 0.75, 0, totalBytes * 1.1); | ||
379 | |||
380 | AssertThrottles( | ||
381 | udpClient2, | ||
382 | resendBytes * 0.75, landBytes * 0.75, windBytes * 0.75, cloudBytes * 0.75, taskBytes * 0.75, | ||
383 | textureBytes * 0.75, assetBytes * 0.75, totalBytes * 0.75, 0, totalBytes * 1.1); | ||
384 | } | ||
385 | |||
386 | private void AssertThrottles( | ||
387 | LLUDPClient udpClient, | ||
388 | double resendBytes, double landBytes, double windBytes, double cloudBytes, double taskBytes, double textureBytes, double assetBytes, | ||
389 | double totalBytes, double targetBytes, double maxBytes) | ||
390 | { | ||
391 | ClientInfo ci = udpClient.GetClientInfo(); | ||
392 | |||
393 | // Console.WriteLine( | ||
394 | // "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}", | ||
395 | // ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle); | ||
396 | |||
397 | Assert.AreEqual((int)resendBytes, ci.resendThrottle, "Resend"); | ||
398 | Assert.AreEqual((int)landBytes, ci.landThrottle, "Land"); | ||
399 | Assert.AreEqual((int)windBytes, ci.windThrottle, "Wind"); | ||
400 | Assert.AreEqual((int)cloudBytes, ci.cloudThrottle, "Cloud"); | ||
401 | Assert.AreEqual((int)taskBytes, ci.taskThrottle, "Task"); | ||
402 | Assert.AreEqual((int)textureBytes, ci.textureThrottle, "Texture"); | ||
403 | Assert.AreEqual((int)assetBytes, ci.assetThrottle, "Asset"); | ||
404 | Assert.AreEqual((int)totalBytes, ci.totalThrottle, "Total"); | ||
405 | Assert.AreEqual((int)targetBytes, ci.targetThrottle, "Target"); | ||
406 | Assert.AreEqual((int)maxBytes, ci.maxThrottle, "Max"); | ||
407 | } | ||
408 | |||
409 | private void SetThrottles( | ||
410 | LLUDPClient udpClient, int resendBytes, int landBytes, int windBytes, int cloudBytes, int taskBytes, int textureBytes, int assetBytes) | ||
411 | { | ||
412 | byte[] throttles = new byte[28]; | ||
413 | |||
414 | Array.Copy(BitConverter.GetBytes((float)resendBytes * 8), 0, throttles, 0, 4); | ||
415 | Array.Copy(BitConverter.GetBytes((float)landBytes * 8), 0, throttles, 4, 4); | ||
416 | Array.Copy(BitConverter.GetBytes((float)windBytes * 8), 0, throttles, 8, 4); | ||
417 | Array.Copy(BitConverter.GetBytes((float)cloudBytes * 8), 0, throttles, 12, 4); | ||
418 | Array.Copy(BitConverter.GetBytes((float)taskBytes * 8), 0, throttles, 16, 4); | ||
419 | Array.Copy(BitConverter.GetBytes((float)textureBytes * 8), 0, throttles, 20, 4); | ||
420 | Array.Copy(BitConverter.GetBytes((float)assetBytes * 8), 0, throttles, 24, 4); | ||
421 | |||
422 | udpClient.SetThrottles(throttles); | ||
423 | } | ||
424 | } | ||
425 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs index e5bae6e..dd15cc7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs | |||
@@ -72,6 +72,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
72 | { | 72 | { |
73 | IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; | 73 | IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; |
74 | 74 | ||
75 | // Current default total is 66750 | ||
75 | Resend = throttleConfig.GetInt("resend_default", 6625); | 76 | Resend = throttleConfig.GetInt("resend_default", 6625); |
76 | Land = throttleConfig.GetInt("land_default", 9125); | 77 | Land = throttleConfig.GetInt("land_default", 9125); |
77 | Wind = throttleConfig.GetInt("wind_default", 1750); | 78 | Wind = throttleConfig.GetInt("wind_default", 1750); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs index 658d9bb..d215595 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs | |||
@@ -42,9 +42,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
42 | public class TokenBucket | 42 | public class TokenBucket |
43 | { | 43 | { |
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | private static Int32 m_counter = 0; | ||
46 | |||
47 | private LLUDPClient m_client; | ||
48 | 45 | ||
49 | public string Identifier { get; private set; } | 46 | public string Identifier { get; private set; } |
50 | 47 | ||
@@ -79,20 +76,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
79 | /// Map of children buckets and their requested maximum burst rate | 76 | /// Map of children buckets and their requested maximum burst rate |
80 | /// </summary> | 77 | /// </summary> |
81 | protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>(); | 78 | protected Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>(); |
82 | |||
83 | #region Properties | ||
84 | 79 | ||
85 | /// <summary> | 80 | /// <summary> |
86 | /// The parent bucket of this bucket, or null if this bucket has no | 81 | /// The parent bucket of this bucket, or null if this bucket has no |
87 | /// parent. The parent bucket will limit the aggregate bandwidth of all | 82 | /// parent. The parent bucket will limit the aggregate bandwidth of all |
88 | /// of its children buckets | 83 | /// of its children buckets |
89 | /// </summary> | 84 | /// </summary> |
90 | protected TokenBucket m_parent; | 85 | public TokenBucket Parent { get; protected set; } |
91 | public TokenBucket Parent | ||
92 | { | ||
93 | get { return m_parent; } | ||
94 | set { m_parent = value; } | ||
95 | } | ||
96 | 86 | ||
97 | /// <summary> | 87 | /// <summary> |
98 | /// Maximum burst rate in bytes per second. This is the maximum number | 88 | /// Maximum burst rate in bytes per second. This is the maximum number |
@@ -118,53 +108,85 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
118 | } | 108 | } |
119 | 109 | ||
120 | /// <summary> | 110 | /// <summary> |
121 | /// The speed limit of this bucket in bytes per second. This is the | 111 | /// The requested drip rate for this particular bucket. |
122 | /// number of tokens that are added to the bucket per quantum | ||
123 | /// </summary> | 112 | /// </summary> |
124 | /// <remarks>Tokens are added to the bucket any time | 113 | /// <remarks> |
114 | /// 0 then TotalDripRequest is used instead. | ||
115 | /// Can never be above MaxDripRate. | ||
116 | /// Tokens are added to the bucket at any time | ||
125 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of | 117 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of |
126 | /// the system tick interval (typically around 15-22ms)</remarks> | 118 | /// the system tick interval (typically around 15-22ms) |
127 | protected Int64 m_dripRate; | 119 | /// FIXME: It is extremely confusing to be able to set a RequestedDripRate of 0 and then receive a positive |
120 | /// number on get if TotalDripRequest is sent. This also stops us being able to retrieve the fact that | ||
121 | /// RequestedDripRate is set to 0. Really, this should always return m_dripRate and then we can get | ||
122 | /// (m_dripRate == 0 ? TotalDripRequest : m_dripRate) on some other properties. | ||
123 | /// </remarks> | ||
128 | public virtual Int64 RequestedDripRate | 124 | public virtual Int64 RequestedDripRate |
129 | { | 125 | { |
130 | get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); } | 126 | get { return (m_dripRate == 0 ? TotalDripRequest : m_dripRate); } |
131 | set { | 127 | set |
132 | m_dripRate = (value < 0 ? 0 : value); | 128 | { |
129 | if (value <= 0) | ||
130 | m_dripRate = 0; | ||
131 | else if (MaxDripRate > 0 && value > MaxDripRate) | ||
132 | m_dripRate = MaxDripRate; | ||
133 | else | ||
134 | m_dripRate = value; | ||
135 | |||
133 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); | 136 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); |
134 | m_totalDripRequest = m_dripRate; | 137 | |
135 | if (m_parent != null) | 138 | if (Parent != null) |
136 | m_parent.RegisterRequest(this,m_dripRate); | 139 | Parent.RegisterRequest(this, m_dripRate); |
137 | } | 140 | } |
138 | } | 141 | } |
139 | 142 | ||
143 | /// <summary> | ||
144 | /// Gets the drip rate. | ||
145 | /// </summary> | ||
146 | /// <value> | ||
147 | /// DripRate can never be above max drip rate or below min drip rate. | ||
148 | /// If we are a child bucket then the drip rate return is modifed by the total load on the capacity of the | ||
149 | /// parent bucket. | ||
150 | /// </value> | ||
140 | public virtual Int64 DripRate | 151 | public virtual Int64 DripRate |
141 | { | 152 | { |
142 | get { | 153 | get |
143 | if (m_parent == null) | 154 | { |
144 | return Math.Min(RequestedDripRate,TotalDripRequest); | 155 | double rate; |
145 | 156 | ||
146 | double rate = (double)RequestedDripRate * m_parent.DripRateModifier(); | 157 | // FIXME: This doesn't properly work if we have a parent and children and a requested drip rate set |
158 | // on ourselves which is not equal to the child drip rates. | ||
159 | if (Parent == null) | ||
160 | { | ||
161 | if (TotalDripRequest > 0) | ||
162 | rate = Math.Min(RequestedDripRate, TotalDripRequest); | ||
163 | else | ||
164 | rate = RequestedDripRate; | ||
165 | } | ||
166 | else | ||
167 | { | ||
168 | rate = (double)RequestedDripRate * Parent.DripRateModifier(); | ||
169 | } | ||
170 | |||
147 | if (rate < m_minimumDripRate) | 171 | if (rate < m_minimumDripRate) |
148 | rate = m_minimumDripRate; | 172 | rate = m_minimumDripRate; |
173 | else if (MaxDripRate > 0 && rate > MaxDripRate) | ||
174 | rate = MaxDripRate; | ||
149 | 175 | ||
150 | return (Int64)rate; | 176 | return (Int64)rate; |
151 | } | 177 | } |
152 | } | 178 | } |
179 | protected Int64 m_dripRate; | ||
180 | |||
181 | // <summary> | ||
182 | // The maximum rate for flow control. Drip rate can never be greater than this. | ||
183 | // </summary> | ||
184 | public Int64 MaxDripRate { get; set; } | ||
153 | 185 | ||
154 | /// <summary> | 186 | /// <summary> |
155 | /// The current total of the requested maximum burst rates of | 187 | /// The current total of the requested maximum burst rates of children buckets. |
156 | /// this bucket's children buckets. | ||
157 | /// </summary> | 188 | /// </summary> |
158 | protected Int64 m_totalDripRequest; | 189 | public Int64 TotalDripRequest { get; protected set; } |
159 | public Int64 TotalDripRequest | ||
160 | { | ||
161 | get { return m_totalDripRequest; } | ||
162 | set { m_totalDripRequest = value; } | ||
163 | } | ||
164 | |||
165 | #endregion Properties | ||
166 | |||
167 | #region Constructor | ||
168 | 190 | ||
169 | /// <summary> | 191 | /// <summary> |
170 | /// Default constructor | 192 | /// Default constructor |
@@ -172,21 +194,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
172 | /// <param name="identifier">Identifier for this token bucket</param> | 194 | /// <param name="identifier">Identifier for this token bucket</param> |
173 | /// <param name="parent">Parent bucket if this is a child bucket, or | 195 | /// <param name="parent">Parent bucket if this is a child bucket, or |
174 | /// null if this is a root bucket</param> | 196 | /// null if this is a root bucket</param> |
175 | /// <param name="dripRate">Rate that the bucket fills, in bytes per | 197 | /// <param name="requestedDripRate"> |
176 | /// second. If zero, the bucket always remains full</param> | 198 | /// Requested rate that the bucket fills, in bytes per |
177 | public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate) | 199 | /// second. If zero, the bucket always remains full. |
200 | /// </param> | ||
201 | public TokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate) | ||
178 | { | 202 | { |
179 | Identifier = identifier; | 203 | Identifier = identifier; |
180 | 204 | ||
181 | Parent = parent; | 205 | Parent = parent; |
182 | RequestedDripRate = dripRate; | 206 | RequestedDripRate = requestedDripRate; |
183 | // TotalDripRequest = dripRate; // this will be overwritten when a child node registers | 207 | MaxDripRate = maxDripRate; |
184 | // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); | ||
185 | m_lastDrip = Util.EnvironmentTickCount(); | 208 | m_lastDrip = Util.EnvironmentTickCount(); |
186 | } | 209 | } |
187 | 210 | ||
188 | #endregion Constructor | ||
189 | |||
190 | /// <summary> | 211 | /// <summary> |
191 | /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning | 212 | /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning |
192 | /// no modification if the requested bandwidth is less than the | 213 | /// no modification if the requested bandwidth is less than the |
@@ -197,7 +218,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
197 | protected double DripRateModifier() | 218 | protected double DripRateModifier() |
198 | { | 219 | { |
199 | Int64 driprate = DripRate; | 220 | Int64 driprate = DripRate; |
200 | return driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest; | 221 | double modifier = driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest; |
222 | |||
223 | // if (DebugLevel > 0) | ||
224 | // m_log.DebugFormat( | ||
225 | // "[TOKEN BUCKET]: Returning drip modifier {0}/{1} = {2} from {3}", | ||
226 | // driprate, TotalDripRequest, modifier, Identifier); | ||
227 | |||
228 | return modifier; | ||
201 | } | 229 | } |
202 | 230 | ||
203 | /// <summary> | 231 | /// <summary> |
@@ -219,16 +247,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
219 | lock (m_children) | 247 | lock (m_children) |
220 | { | 248 | { |
221 | m_children[child] = request; | 249 | m_children[child] = request; |
222 | // m_totalDripRequest = m_children.Values.Sum(); | ||
223 | 250 | ||
224 | m_totalDripRequest = 0; | 251 | TotalDripRequest = 0; |
225 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | 252 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) |
226 | m_totalDripRequest += cref.Value; | 253 | TotalDripRequest += cref.Value; |
227 | } | 254 | } |
228 | 255 | ||
229 | // Pass the new values up to the parent | 256 | // Pass the new values up to the parent |
230 | if (m_parent != null) | 257 | if (Parent != null) |
231 | m_parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); | 258 | { |
259 | Int64 effectiveDripRate; | ||
260 | |||
261 | if (RequestedDripRate > 0) | ||
262 | effectiveDripRate = Math.Min(RequestedDripRate, TotalDripRequest); | ||
263 | else | ||
264 | effectiveDripRate = TotalDripRequest; | ||
265 | |||
266 | Parent.RegisterRequest(this, effectiveDripRate); | ||
267 | } | ||
232 | } | 268 | } |
233 | 269 | ||
234 | /// <summary> | 270 | /// <summary> |
@@ -240,17 +276,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
240 | lock (m_children) | 276 | lock (m_children) |
241 | { | 277 | { |
242 | m_children.Remove(child); | 278 | m_children.Remove(child); |
243 | // m_totalDripRequest = m_children.Values.Sum(); | ||
244 | 279 | ||
245 | m_totalDripRequest = 0; | 280 | TotalDripRequest = 0; |
246 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | 281 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) |
247 | m_totalDripRequest += cref.Value; | 282 | TotalDripRequest += cref.Value; |
248 | } | 283 | } |
249 | |||
250 | 284 | ||
251 | // Pass the new values up to the parent | 285 | // Pass the new values up to the parent |
252 | if (m_parent != null) | 286 | if (Parent != null) |
253 | m_parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); | 287 | Parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); |
254 | } | 288 | } |
255 | 289 | ||
256 | /// <summary> | 290 | /// <summary> |
@@ -323,64 +357,66 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
323 | 357 | ||
324 | public class AdaptiveTokenBucket : TokenBucket | 358 | public class AdaptiveTokenBucket : TokenBucket |
325 | { | 359 | { |
326 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 360 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
361 | |||
362 | public bool AdaptiveEnabled { get; set; } | ||
327 | 363 | ||
328 | /// <summary> | 364 | /// <summary> |
329 | /// The minimum rate for flow control. Minimum drip rate is one | 365 | /// Target drip rate for this bucket. |
330 | /// packet per second. Open the throttle to 15 packets per second | ||
331 | /// or about 160kbps. | ||
332 | /// </summary> | 366 | /// </summary> |
333 | protected const Int64 m_minimumFlow = m_minimumDripRate * 15; | 367 | /// <remarks>Usually set by the client. If adaptive is enabled then throttles will increase until we reach this.</remarks> |
334 | 368 | public Int64 TargetDripRate | |
335 | // <summary> | 369 | { |
336 | // The maximum rate for flow control. Drip rate can never be | 370 | get { return m_targetDripRate; } |
337 | // greater than this. | 371 | set |
338 | // </summary> | 372 | { |
339 | protected Int64 m_maxDripRate = 0; | 373 | m_targetDripRate = Math.Max(value, m_minimumFlow); |
340 | public Int64 MaxDripRate | 374 | } |
341 | { | ||
342 | get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); } | ||
343 | protected set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); } | ||
344 | } | 375 | } |
376 | protected Int64 m_targetDripRate; | ||
345 | 377 | ||
346 | public bool Enabled { get; private set; } | ||
347 | |||
348 | // <summary> | 378 | // <summary> |
349 | // | 379 | // Adjust drip rate in response to network conditions. |
350 | // </summary> | 380 | // </summary> |
351 | public virtual Int64 AdjustedDripRate | 381 | public virtual Int64 AdjustedDripRate |
352 | { | 382 | { |
353 | get { return m_dripRate; } | 383 | get { return m_dripRate; } |
354 | set { | 384 | set |
355 | m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value,m_minimumFlow,MaxDripRate); | 385 | { |
386 | m_dripRate = OpenSim.Framework.Util.Clamp<Int64>(value, m_minimumFlow, TargetDripRate); | ||
356 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); | 387 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); |
357 | if (m_parent != null) | 388 | |
358 | m_parent.RegisterRequest(this,m_dripRate); | 389 | if (Parent != null) |
390 | Parent.RegisterRequest(this, m_dripRate); | ||
359 | } | 391 | } |
360 | } | 392 | } |
393 | |||
394 | /// <summary> | ||
395 | /// The minimum rate for flow control. Minimum drip rate is one | ||
396 | /// packet per second. Open the throttle to 15 packets per second | ||
397 | /// or about 160kbps. | ||
398 | /// </summary> | ||
399 | protected const Int64 m_minimumFlow = m_minimumDripRate * 15; | ||
361 | 400 | ||
362 | // <summary> | 401 | public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 requestedDripRate, Int64 maxDripRate, bool enabled) |
363 | // | 402 | : base(identifier, parent, requestedDripRate, maxDripRate) |
364 | // </summary> | ||
365 | public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 maxDripRate, bool enabled) | ||
366 | : base(identifier, parent, maxDripRate) | ||
367 | { | 403 | { |
368 | Enabled = enabled; | 404 | AdaptiveEnabled = enabled; |
369 | 405 | ||
370 | if (Enabled) | 406 | if (AdaptiveEnabled) |
371 | { | 407 | { |
372 | // m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled"); | 408 | // m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled"); |
373 | MaxDripRate = maxDripRate; | 409 | TargetDripRate = m_minimumFlow; |
374 | AdjustedDripRate = m_minimumFlow; | 410 | AdjustedDripRate = m_minimumFlow; |
375 | } | 411 | } |
376 | } | 412 | } |
377 | 413 | ||
378 | // <summary> | 414 | // <summary> |
379 | // | 415 | // Reliable packets sent to the client for which we never received an ack adjust the drip rate down. |
380 | // </summary> | 416 | // </summary> |
381 | public void ExpirePackets(Int32 count) | 417 | public void ExpirePackets(Int32 count) |
382 | { | 418 | { |
383 | if (Enabled) | 419 | if (AdaptiveEnabled) |
384 | { | 420 | { |
385 | if (DebugLevel > 0) | 421 | if (DebugLevel > 0) |
386 | m_log.WarnFormat( | 422 | m_log.WarnFormat( |
@@ -392,12 +428,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
392 | } | 428 | } |
393 | 429 | ||
394 | // <summary> | 430 | // <summary> |
395 | // | 431 | // Reliable packets acked by the client adjust the drip rate up. |
396 | // </summary> | 432 | // </summary> |
397 | public void AcknowledgePackets(Int32 count) | 433 | public void AcknowledgePackets(Int32 count) |
398 | { | 434 | { |
399 | if (Enabled) | 435 | if (AdaptiveEnabled) |
400 | AdjustedDripRate = AdjustedDripRate + count; | 436 | AdjustedDripRate = AdjustedDripRate + count; |
401 | } | 437 | } |
402 | } | 438 | } |
403 | } | 439 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 5cdcab9..47dcbcd 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs | |||
@@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
167 | 167 | ||
168 | // Do Decode! | 168 | // Do Decode! |
169 | if (decode) | 169 | if (decode) |
170 | Util.FireAndForget(delegate { Decode(assetID, j2kData); }); | 170 | Util.FireAndForget(delegate { Decode(assetID, j2kData); }, null, "J2KDecoderModule.BeginDecode"); |
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 9d6870f..fe9a17d 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -302,7 +302,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
302 | } | 302 | } |
303 | 303 | ||
304 | Util.FireAndForget( | 304 | Util.FireAndForget( |
305 | delegate { WriteFileCache(filename, asset); }); | 305 | delegate { WriteFileCache(filename, asset); }, null, "FlotsamAssetCache.UpdateFileCache"); |
306 | } | 306 | } |
307 | } | 307 | } |
308 | catch (Exception e) | 308 | catch (Exception e) |
@@ -964,11 +964,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
964 | case "assets": | 964 | case "assets": |
965 | con.Output("Ensuring assets are cached for all scenes."); | 965 | con.Output("Ensuring assets are cached for all scenes."); |
966 | 966 | ||
967 | Watchdog.RunInThread(delegate | 967 | WorkManager.RunInThread(delegate |
968 | { | 968 | { |
969 | int assetReferenceTotal = TouchAllSceneAssets(true); | 969 | int assetReferenceTotal = TouchAllSceneAssets(true); |
970 | con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); | 970 | con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); |
971 | }, "TouchAllSceneAssets", null); | 971 | }, null, "TouchAllSceneAssets"); |
972 | 972 | ||
973 | break; | 973 | break; |
974 | 974 | ||
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index fd02b08..73e4431 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | |||
@@ -39,7 +39,6 @@ using OpenSim.Framework; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.Framework.Scenes.Serialization; | 40 | using OpenSim.Region.Framework.Scenes.Serialization; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Region.CoreModules.Asset.Tests | 43 | namespace OpenSim.Region.CoreModules.Asset.Tests |
45 | { | 44 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 3bd7bee..5fb995b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -53,7 +53,6 @@ using OpenSim.Region.ScriptEngine.Interfaces; | |||
53 | using OpenSim.Region.ScriptEngine.XEngine; | 53 | using OpenSim.Region.ScriptEngine.XEngine; |
54 | using OpenSim.Services.Interfaces; | 54 | using OpenSim.Services.Interfaces; |
55 | using OpenSim.Tests.Common; | 55 | using OpenSim.Tests.Common; |
56 | using OpenSim.Tests.Common.Mock; | ||
57 | 56 | ||
58 | namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | 57 | namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests |
59 | { | 58 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index d8c159f..ea7481d 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -593,7 +593,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
593 | 593 | ||
594 | if (sendTime < now) | 594 | if (sendTime < now) |
595 | { | 595 | { |
596 | Util.FireAndForget(o => SendAppearance(avatarID)); | 596 | Util.FireAndForget(o => SendAppearance(avatarID), null, "AvatarFactoryModule.SendAppearance"); |
597 | m_sendqueue.Remove(avatarID); | 597 | m_sendqueue.Remove(avatarID); |
598 | } | 598 | } |
599 | } | 599 | } |
@@ -611,7 +611,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
611 | 611 | ||
612 | if (sendTime < now) | 612 | if (sendTime < now) |
613 | { | 613 | { |
614 | Util.FireAndForget(o => SaveAppearance(avatarID)); | 614 | Util.FireAndForget(o => SaveAppearance(avatarID), null, "AvatarFactoryModule.SaveAppearance"); |
615 | m_savequeue.Remove(avatarID); | 615 | m_savequeue.Remove(avatarID); |
616 | } | 616 | } |
617 | } | 617 | } |
@@ -1038,7 +1038,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1038 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); | 1038 | client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); |
1039 | else | 1039 | else |
1040 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); | 1040 | m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); |
1041 | }); | 1041 | }, null, "AvatarFactoryModule.OnClientRequestWearables"); |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | /// <summary> | 1044 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index de014ba..9513408 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | |||
@@ -34,7 +34,6 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Region.CoreModules.Asset; | 34 | using OpenSim.Region.CoreModules.Asset; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | 38 | namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory |
40 | { | 39 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs index 5725d67..5e35135 100644 --- a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs | |||
@@ -187,7 +187,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures | |||
187 | { | 187 | { |
188 | rc.Request(reqStream, m_Auth); | 188 | rc.Request(reqStream, m_Auth); |
189 | m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId); | 189 | m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId); |
190 | } | 190 | }, null, "XBakesModule.Store" |
191 | ); | 191 | ); |
192 | } | 192 | } |
193 | } | 193 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs index 7b8c418..3018d94 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs | |||
@@ -41,7 +41,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Services.Interfaces; | 42 | using OpenSim.Services.Interfaces; |
43 | using OpenSim.Tests.Common; | 43 | using OpenSim.Tests.Common; |
44 | using OpenSim.Tests.Common.Mock; | ||
45 | 44 | ||
46 | namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests | 45 | namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests |
47 | { | 46 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 31bcded..7ab568e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -511,7 +511,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
511 | 511 | ||
512 | // Notify about this user status | 512 | // Notify about this user status |
513 | StatusNotify(friendList, agentID, online); | 513 | StatusNotify(friendList, agentID, online); |
514 | } | 514 | }, null, "FriendsModule.StatusChange" |
515 | ); | 515 | ); |
516 | } | 516 | } |
517 | } | 517 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index be12935..27b7376 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -660,7 +660,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
660 | FriendsService.Delete(friendUUI, agentID.ToString()); | 660 | FriendsService.Delete(friendUUI, agentID.ToString()); |
661 | 661 | ||
662 | // notify the exfriend's service | 662 | // notify the exfriend's service |
663 | Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); }); | 663 | Util.FireAndForget( |
664 | delegate { Delete(exfriendID, agentID, friendUUI); }, null, "HGFriendsModule.DeleteFriendshipForeignFriend"); | ||
664 | 665 | ||
665 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); | 666 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); |
666 | return true; | 667 | return true; |
@@ -678,7 +679,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
678 | FriendsService.Delete(agentUUI, exfriendID.ToString()); | 679 | FriendsService.Delete(agentUUI, exfriendID.ToString()); |
679 | 680 | ||
680 | // notify the agent's service? | 681 | // notify the agent's service? |
681 | Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); }); | 682 | Util.FireAndForget( |
683 | delegate { Delete(agentID, exfriendID, agentUUI); }, null, "HGFriendsModule.DeleteFriendshipLocalFriend"); | ||
682 | 684 | ||
683 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); | 685 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); |
684 | return true; | 686 | return true; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 961117e..e6fd54e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs | |||
@@ -35,7 +35,6 @@ using OpenSim.Framework; | |||
35 | using OpenSim.Region.CoreModules.Avatar.Friends; | 35 | using OpenSim.Region.CoreModules.Avatar.Friends; |
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Tests.Common; | 37 | using OpenSim.Tests.Common; |
38 | using OpenSim.Tests.Common.Mock; | ||
39 | 38 | ||
40 | namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | 39 | namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests |
41 | { | 40 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index 6f3c80a..a1b918a 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs | |||
@@ -213,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
213 | HandleUndeliverableMessage(im, result); | 213 | HandleUndeliverableMessage(im, result); |
214 | else | 214 | else |
215 | result(success); | 215 | result(success); |
216 | }); | 216 | }, null, "HGMessageTransferModule.SendInstantMessage"); |
217 | 217 | ||
218 | return; | 218 | return; |
219 | } | 219 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 9fb8aa5..6dab227 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -431,7 +431,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
431 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | 431 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, |
432 | options, ReceivedAllAssets); | 432 | options, ReceivedAllAssets); |
433 | 433 | ||
434 | Watchdog.RunInThread(o => ar.Execute(), string.Format("AssetsRequest ({0})", m_scene.Name), null); | 434 | WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name)); |
435 | } | 435 | } |
436 | else | 436 | else |
437 | { | 437 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index 8d7de14..84f9f3f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes; | |||
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 43 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 44 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 47 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs index 3f16a16..d5f3a22 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes; | |||
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 43 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 44 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 47 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs index 4791a79..b614c18 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes; | |||
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 43 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 44 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 47 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index e2d95da..4b015d7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes; | |||
43 | using OpenSim.Region.Framework.Scenes.Serialization; | 43 | using OpenSim.Region.Framework.Scenes.Serialization; |
44 | using OpenSim.Services.Interfaces; | 44 | using OpenSim.Services.Interfaces; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 47 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs index 162a0c3..d615cce 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs | |||
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests | 43 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests |
45 | { | 44 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 8337a2f..546a121 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | |||
@@ -194,7 +194,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles | |||
194 | Util.FireAndForget(delegate | 194 | Util.FireAndForget(delegate |
195 | { | 195 | { |
196 | GetImageAssets(((IScenePresence)obj).UUID); | 196 | GetImageAssets(((IScenePresence)obj).UUID); |
197 | }); | 197 | }, null, "UserProfileModule.GetImageAssets"); |
198 | } | 198 | } |
199 | 199 | ||
200 | /// <summary> | 200 | /// <summary> |
@@ -921,8 +921,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles | |||
921 | object Pref = (object)pref; | 921 | object Pref = (object)pref; |
922 | if(!rpc.JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString())) | 922 | if(!rpc.JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString())) |
923 | { | 923 | { |
924 | m_log.InfoFormat("[PROFILES]: UserPreferences request error"); | 924 | // m_log.InfoFormat("[PROFILES]: UserPreferences request error"); |
925 | remoteClient.SendAgentAlertMessage("Error requesting preferences", false); | 925 | // remoteClient.SendAgentAlertMessage("Error requesting preferences", false); |
926 | return; | 926 | return; |
927 | } | 927 | } |
928 | pref = (UserPreferences) Pref; | 928 | pref = (UserPreferences) Pref; |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index c43633c..09e8204 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -804,8 +804,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
804 | // once we reach here... | 804 | // once we reach here... |
805 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | 805 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); |
806 | 806 | ||
807 | string capsPath = String.Empty; | ||
808 | |||
809 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 807 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
810 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | 808 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); |
811 | agentCircuit.startpos = position; | 809 | agentCircuit.startpos = position; |
@@ -2702,5 +2700,69 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
2702 | } | 2700 | } |
2703 | #endregion | 2701 | #endregion |
2704 | 2702 | ||
2703 | public virtual bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition) | ||
2704 | { | ||
2705 | // If the user is banned, we won't let any of their objects | ||
2706 | // enter. Period. | ||
2707 | // | ||
2708 | if (Scene.RegionInfo.EstateSettings.IsBanned(so.OwnerID)) | ||
2709 | { | ||
2710 | m_log.DebugFormat( | ||
2711 | "[ENTITY TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}", | ||
2712 | so.Name, so.UUID, Scene.Name, so.OwnerID); | ||
2713 | |||
2714 | return false; | ||
2715 | } | ||
2716 | |||
2717 | if (newPosition != Vector3.Zero) | ||
2718 | so.RootPart.GroupPosition = newPosition; | ||
2719 | |||
2720 | if (!Scene.AddSceneObject(so)) | ||
2721 | { | ||
2722 | m_log.DebugFormat( | ||
2723 | "[ENTITY TRANSFER MODULE]: Problem adding scene object {0} {1} into {2} ", | ||
2724 | so.Name, so.UUID, Scene.Name); | ||
2725 | |||
2726 | return false; | ||
2727 | } | ||
2728 | |||
2729 | if (!so.IsAttachment) | ||
2730 | { | ||
2731 | // FIXME: It would be better to never add the scene object at all rather than add it and then delete | ||
2732 | // it | ||
2733 | if (!Scene.Permissions.CanObjectEntry(so.UUID, true, so.AbsolutePosition)) | ||
2734 | { | ||
2735 | // Deny non attachments based on parcel settings | ||
2736 | // | ||
2737 | m_log.Info("[ENTITY TRANSFER MODULE]: Denied prim crossing because of parcel settings"); | ||
2738 | |||
2739 | Scene.DeleteSceneObject(so, false); | ||
2740 | |||
2741 | return false; | ||
2742 | } | ||
2743 | |||
2744 | // For attachments, we need to wait until the agent is root | ||
2745 | // before we restart the scripts, or else some functions won't work. | ||
2746 | so.RootPart.ParentGroup.CreateScriptInstances( | ||
2747 | 0, false, Scene.DefaultScriptEngine, GetStateSource(so)); | ||
2748 | |||
2749 | so.ResumeScripts(); | ||
2750 | |||
2751 | if (so.RootPart.KeyframeMotion != null) | ||
2752 | so.RootPart.KeyframeMotion.UpdateSceneObject(so); | ||
2753 | } | ||
2754 | |||
2755 | return true; | ||
2756 | } | ||
2757 | |||
2758 | private int GetStateSource(SceneObjectGroup sog) | ||
2759 | { | ||
2760 | ScenePresence sp = Scene.GetScenePresence(sog.OwnerID); | ||
2761 | |||
2762 | if (sp != null) | ||
2763 | return sp.GetStateSource(); | ||
2764 | |||
2765 | return 2; // StateSource.PrimCrossing | ||
2766 | } | ||
2705 | } | 2767 | } |
2706 | } | 2768 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 0c0cdf2..97267c1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -110,6 +110,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | 112 | ||
113 | /// <summary> | ||
114 | /// Used for processing analysis of incoming attachments in a controlled fashion. | ||
115 | /// </summary> | ||
116 | private HGIncomingSceneObjectEngine m_incomingSceneObjectEngine; | ||
117 | |||
113 | #region ISharedRegionModule | 118 | #region ISharedRegionModule |
114 | 119 | ||
115 | public override string Name | 120 | public override string Name |
@@ -153,33 +158,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
153 | if (m_Enabled) | 158 | if (m_Enabled) |
154 | { | 159 | { |
155 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); | 160 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); |
156 | scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject; | 161 | //scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject; |
157 | } | ||
158 | } | ||
159 | 162 | ||
160 | void OnIncomingSceneObject(SceneObjectGroup so) | 163 | m_incomingSceneObjectEngine = new HGIncomingSceneObjectEngine(scene.Name); |
161 | { | 164 | m_incomingSceneObjectEngine.Start(); |
162 | if (!so.IsAttachment) | ||
163 | return; | ||
164 | |||
165 | if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) | ||
166 | return; | ||
167 | |||
168 | // foreign user | ||
169 | AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); | ||
170 | if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) | ||
171 | { | ||
172 | if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | ||
173 | { | ||
174 | string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | ||
175 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); | ||
176 | Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); | ||
177 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url); | ||
178 | uuidGatherer.GatherAssetUuids(so, ids); | ||
179 | |||
180 | foreach (KeyValuePair<UUID, sbyte> kvp in ids) | ||
181 | uuidGatherer.FetchAsset(kvp.Key); | ||
182 | } | ||
183 | } | 165 | } |
184 | } | 166 | } |
185 | 167 | ||
@@ -209,12 +191,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
209 | base.RemoveRegion(scene); | 191 | base.RemoveRegion(scene); |
210 | 192 | ||
211 | if (m_Enabled) | 193 | if (m_Enabled) |
194 | { | ||
212 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); | 195 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); |
196 | m_incomingSceneObjectEngine.Stop(); | ||
197 | } | ||
213 | } | 198 | } |
214 | 199 | ||
215 | #endregion | 200 | #endregion |
216 | 201 | ||
217 | #region HG overrides of IEntiryTransferModule | 202 | #region HG overrides of IEntityTransferModule |
218 | 203 | ||
219 | protected override GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) | 204 | protected override GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) |
220 | { | 205 | { |
@@ -561,6 +546,132 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
561 | } | 546 | } |
562 | } | 547 | } |
563 | 548 | ||
549 | private void RemoveIncomingSceneObjectJobs(string commonIdToRemove) | ||
550 | { | ||
551 | List<Job> jobsToReinsert = new List<Job>(); | ||
552 | int jobsRemoved = 0; | ||
553 | |||
554 | Job job; | ||
555 | while ((job = m_incomingSceneObjectEngine.RemoveNextRequest()) != null) | ||
556 | { | ||
557 | if (job.CommonId != commonIdToRemove) | ||
558 | jobsToReinsert.Add(job); | ||
559 | else | ||
560 | jobsRemoved++; | ||
561 | } | ||
562 | |||
563 | m_log.DebugFormat( | ||
564 | "[HG ENTITY TRANSFER]: Removing {0} jobs with common ID {1} and reinserting {2} other jobs", | ||
565 | jobsRemoved, commonIdToRemove, jobsToReinsert.Count); | ||
566 | |||
567 | if (jobsToReinsert.Count > 0) | ||
568 | { | ||
569 | foreach (Job jobToReinsert in jobsToReinsert) | ||
570 | m_incomingSceneObjectEngine.QueueRequest(jobToReinsert); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition) | ||
575 | { | ||
576 | // FIXME: We must make it so that we can use SOG.IsAttachment here. At the moment it is always null! | ||
577 | if (!so.IsAttachmentCheckFull()) | ||
578 | return base.HandleIncomingSceneObject(so, newPosition); | ||
579 | |||
580 | // Equally, we can't use so.AttachedAvatar here. | ||
581 | if (so.OwnerID == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.OwnerID)) | ||
582 | return base.HandleIncomingSceneObject(so, newPosition); | ||
583 | |||
584 | // foreign user | ||
585 | AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.OwnerID); | ||
586 | if (aCircuit != null) | ||
587 | { | ||
588 | if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) == 0) | ||
589 | { | ||
590 | // We have already pulled the necessary attachments from the source grid. | ||
591 | base.HandleIncomingSceneObject(so, newPosition); | ||
592 | } | ||
593 | else | ||
594 | { | ||
595 | if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | ||
596 | { | ||
597 | m_incomingSceneObjectEngine.QueueRequest( | ||
598 | string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name), | ||
599 | so.OwnerID.ToString(), | ||
600 | o => | ||
601 | { | ||
602 | string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | ||
603 | // m_log.DebugFormat( | ||
604 | // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}", | ||
605 | // so.Name, so.AttachedAvatar, url); | ||
606 | |||
607 | IteratingHGUuidGatherer uuidGatherer = new IteratingHGUuidGatherer(Scene.AssetService, url); | ||
608 | uuidGatherer.RecordAssetUuids(so); | ||
609 | |||
610 | while (!uuidGatherer.Complete) | ||
611 | { | ||
612 | int tickStart = Util.EnvironmentTickCount(); | ||
613 | |||
614 | UUID? nextUuid = uuidGatherer.NextUuidToInspect; | ||
615 | uuidGatherer.GatherNext(); | ||
616 | |||
617 | // m_log.DebugFormat( | ||
618 | // "[HG ENTITY TRANSFER]: Gathered attachment asset uuid {0} for object {1} for HG user {2} took {3} ms with asset service {4}", | ||
619 | // nextUuid, so.Name, so.OwnerID, Util.EnvironmentTickCountSubtract(tickStart), url); | ||
620 | |||
621 | int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart); | ||
622 | |||
623 | if (ticksElapsed > 30000) | ||
624 | { | ||
625 | m_log.WarnFormat( | ||
626 | "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as gather of {1} from {2} took {3} ms to respond (> {4} ms)", | ||
627 | so.OwnerID, so.Name, url, ticksElapsed, 30000); | ||
628 | |||
629 | RemoveIncomingSceneObjectJobs(so.OwnerID.ToString()); | ||
630 | |||
631 | return; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | IDictionary<UUID, sbyte> ids = uuidGatherer.GetGatheredUuids(); | ||
636 | |||
637 | // m_log.DebugFormat( | ||
638 | // "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}", | ||
639 | // ids.Count, so.Name, so.OwnerID, url); | ||
640 | |||
641 | foreach (KeyValuePair<UUID, sbyte> kvp in ids) | ||
642 | { | ||
643 | int tickStart = Util.EnvironmentTickCount(); | ||
644 | |||
645 | uuidGatherer.FetchAsset(kvp.Key); | ||
646 | |||
647 | int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart); | ||
648 | |||
649 | if (ticksElapsed > 30000) | ||
650 | { | ||
651 | m_log.WarnFormat( | ||
652 | "[HG ENTITY TRANSFER]: Removing incoming scene object jobs for HG user {0} as fetch of {1} from {2} took {3} ms to respond (> {4} ms)", | ||
653 | so.OwnerID, kvp.Key, url, ticksElapsed, 30000); | ||
654 | |||
655 | RemoveIncomingSceneObjectJobs(so.OwnerID.ToString()); | ||
656 | |||
657 | return; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | base.HandleIncomingSceneObject(so, newPosition); | ||
662 | |||
663 | // m_log.DebugFormat( | ||
664 | // "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}", | ||
665 | // so.Name, so.OwnerID, url); | ||
666 | }, | ||
667 | null); | ||
668 | } | ||
669 | } | ||
670 | } | ||
671 | |||
672 | return true; | ||
673 | } | ||
674 | |||
564 | #endregion | 675 | #endregion |
565 | 676 | ||
566 | #region IUserAgentVerificationModule | 677 | #region IUserAgentVerificationModule |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs new file mode 100644 index 0000000..f62e7f4 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGIncomingSceneObjectEngine.cs | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Concurrent; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using log4net; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Monitoring; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | |||
37 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | ||
38 | { | ||
39 | public class Job | ||
40 | { | ||
41 | public string Name { get; private set; } | ||
42 | public string CommonId { get; private set; } | ||
43 | public WaitCallback Callback { get; private set; } | ||
44 | public object O { get; private set; } | ||
45 | |||
46 | public Job(string name, string commonId, WaitCallback callback, object o) | ||
47 | { | ||
48 | Name = name; | ||
49 | CommonId = commonId; | ||
50 | Callback = callback; | ||
51 | O = o; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | // TODO: These kinds of classes MUST be generalized with JobEngine, etc. | ||
56 | public class HGIncomingSceneObjectEngine | ||
57 | { | ||
58 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
59 | |||
60 | public int LogLevel { get; set; } | ||
61 | |||
62 | public bool IsRunning { get; private set; } | ||
63 | |||
64 | public string Name { get; set; } | ||
65 | |||
66 | /// <summary> | ||
67 | /// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping. | ||
68 | /// </summary> | ||
69 | public int RequestProcessTimeoutOnStop { get; set; } | ||
70 | |||
71 | /// <summary> | ||
72 | /// Controls whether we need to warn in the log about exceeding the max queue size. | ||
73 | /// </summary> | ||
74 | /// <remarks> | ||
75 | /// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in | ||
76 | /// order to avoid spamming the log with lots of warnings. | ||
77 | /// </remarks> | ||
78 | private bool m_warnOverMaxQueue = true; | ||
79 | |||
80 | private BlockingCollection<Job> m_requestQueue; | ||
81 | |||
82 | private CancellationTokenSource m_cancelSource = new CancellationTokenSource(); | ||
83 | |||
84 | private Stat m_requestsWaitingStat; | ||
85 | |||
86 | private Job m_currentJob; | ||
87 | |||
88 | /// <summary> | ||
89 | /// Used to signal that we are ready to complete stop. | ||
90 | /// </summary> | ||
91 | private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false); | ||
92 | |||
93 | public HGIncomingSceneObjectEngine(string name) | ||
94 | { | ||
95 | // LogLevel = 1; | ||
96 | Name = name; | ||
97 | RequestProcessTimeoutOnStop = 5000; | ||
98 | |||
99 | // MainConsole.Instance.Commands.AddCommand( | ||
100 | // "Debug", | ||
101 | // false, | ||
102 | // "debug jobengine", | ||
103 | // "debug jobengine <start|stop|status>", | ||
104 | // "Start, stop or get status of the job engine.", | ||
105 | // "If stopped then all jobs are processed immediately.", | ||
106 | // HandleControlCommand); | ||
107 | } | ||
108 | |||
109 | public void Start() | ||
110 | { | ||
111 | lock (this) | ||
112 | { | ||
113 | if (IsRunning) | ||
114 | return; | ||
115 | |||
116 | IsRunning = true; | ||
117 | |||
118 | m_finishedProcessingAfterStop.Reset(); | ||
119 | |||
120 | m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000); | ||
121 | |||
122 | m_requestsWaitingStat = | ||
123 | new Stat( | ||
124 | "HGIncomingAttachmentsWaiting", | ||
125 | "Number of incoming attachments waiting for processing.", | ||
126 | "", | ||
127 | "", | ||
128 | "entitytransfer", | ||
129 | Name, | ||
130 | StatType.Pull, | ||
131 | MeasuresOfInterest.None, | ||
132 | stat => stat.Value = m_requestQueue.Count, | ||
133 | StatVerbosity.Debug); | ||
134 | |||
135 | StatsManager.RegisterStat(m_requestsWaitingStat); | ||
136 | |||
137 | WorkManager.StartThread( | ||
138 | ProcessRequests, | ||
139 | string.Format("HG Incoming Scene Object Engine Thread ({0})", Name), | ||
140 | ThreadPriority.Normal, | ||
141 | false, | ||
142 | true, | ||
143 | null, | ||
144 | int.MaxValue); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | public void Stop() | ||
149 | { | ||
150 | lock (this) | ||
151 | { | ||
152 | try | ||
153 | { | ||
154 | if (!IsRunning) | ||
155 | return; | ||
156 | |||
157 | IsRunning = false; | ||
158 | |||
159 | int requestsLeft = m_requestQueue.Count; | ||
160 | |||
161 | if (requestsLeft <= 0) | ||
162 | { | ||
163 | m_cancelSource.Cancel(); | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | m_log.InfoFormat("[HG INCOMING SCENE OBJECT ENGINE]: Waiting to write {0} events after stop.", requestsLeft); | ||
168 | |||
169 | while (requestsLeft > 0) | ||
170 | { | ||
171 | if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop)) | ||
172 | { | ||
173 | // After timeout no events have been written | ||
174 | if (requestsLeft == m_requestQueue.Count) | ||
175 | { | ||
176 | m_log.WarnFormat( | ||
177 | "[HG INCOMING SCENE OBJECT ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests", | ||
178 | RequestProcessTimeoutOnStop, requestsLeft); | ||
179 | |||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | requestsLeft = m_requestQueue.Count; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | finally | ||
189 | { | ||
190 | m_cancelSource.Dispose(); | ||
191 | StatsManager.DeregisterStat(m_requestsWaitingStat); | ||
192 | m_requestsWaitingStat = null; | ||
193 | m_requestQueue = null; | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | |||
198 | public Job RemoveNextRequest() | ||
199 | { | ||
200 | Job nextRequest; | ||
201 | m_requestQueue.TryTake(out nextRequest); | ||
202 | |||
203 | return nextRequest; | ||
204 | } | ||
205 | |||
206 | public bool QueueRequest(string name, string commonId, WaitCallback req, object o) | ||
207 | { | ||
208 | return QueueRequest(new Job(name, commonId, req, o)); | ||
209 | } | ||
210 | |||
211 | public bool QueueRequest(Job job) | ||
212 | { | ||
213 | if (LogLevel >= 1) | ||
214 | m_log.DebugFormat( | ||
215 | "[HG INCOMING SCENE OBJECT ENGINE]: Queued job {0}, common ID {1}", job.Name, job.CommonId); | ||
216 | |||
217 | if (m_requestQueue.Count < m_requestQueue.BoundedCapacity) | ||
218 | { | ||
219 | // m_log.DebugFormat( | ||
220 | // "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}", | ||
221 | // categories, client.AgentID, m_udpServer.Scene.Name); | ||
222 | |||
223 | m_requestQueue.Add(job); | ||
224 | |||
225 | if (!m_warnOverMaxQueue) | ||
226 | m_warnOverMaxQueue = true; | ||
227 | |||
228 | return true; | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | if (m_warnOverMaxQueue) | ||
233 | { | ||
234 | // m_log.WarnFormat( | ||
235 | // "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}", | ||
236 | // client.AgentID, m_udpServer.Scene.Name); | ||
237 | |||
238 | m_log.WarnFormat("[HG INCOMING SCENE OBJECT ENGINE]: Request queue at maximum capacity, not recording job"); | ||
239 | |||
240 | m_warnOverMaxQueue = false; | ||
241 | } | ||
242 | |||
243 | return false; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | private void ProcessRequests() | ||
248 | { | ||
249 | try | ||
250 | { | ||
251 | while (IsRunning || m_requestQueue.Count > 0) | ||
252 | { | ||
253 | m_currentJob = m_requestQueue.Take(m_cancelSource.Token); | ||
254 | |||
255 | // QueueEmpty callback = req.Client.OnQueueEmpty; | ||
256 | // | ||
257 | // if (callback != null) | ||
258 | // { | ||
259 | // try | ||
260 | // { | ||
261 | // callback(req.Categories); | ||
262 | // } | ||
263 | // catch (Exception e) | ||
264 | // { | ||
265 | // m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e); | ||
266 | // } | ||
267 | // } | ||
268 | |||
269 | if (LogLevel >= 1) | ||
270 | m_log.DebugFormat("[HG INCOMING SCENE OBJECT ENGINE]: Processing job {0}", m_currentJob.Name); | ||
271 | |||
272 | try | ||
273 | { | ||
274 | m_currentJob.Callback.Invoke(m_currentJob.O); | ||
275 | } | ||
276 | catch (Exception e) | ||
277 | { | ||
278 | m_log.Error( | ||
279 | string.Format( | ||
280 | "[HG INCOMING SCENE OBJECT ENGINE]: Job {0} failed, continuing. Exception ", m_currentJob.Name), e); | ||
281 | } | ||
282 | |||
283 | if (LogLevel >= 1) | ||
284 | m_log.DebugFormat("[HG INCOMING SCENE OBJECT ENGINE]: Processed job {0}", m_currentJob.Name); | ||
285 | |||
286 | m_currentJob = null; | ||
287 | } | ||
288 | } | ||
289 | catch (OperationCanceledException) | ||
290 | { | ||
291 | } | ||
292 | |||
293 | m_finishedProcessingAfterStop.Set(); | ||
294 | } | ||
295 | |||
296 | // private void HandleControlCommand(string module, string[] args) | ||
297 | // { | ||
298 | // // if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
299 | // // return; | ||
300 | // | ||
301 | // if (args.Length < 3) | ||
302 | // { | ||
303 | // MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|loglevel>"); | ||
304 | // return; | ||
305 | // } | ||
306 | // | ||
307 | // string subCommand = args[2]; | ||
308 | // | ||
309 | // if (subCommand == "stop") | ||
310 | // { | ||
311 | // Stop(); | ||
312 | // MainConsole.Instance.OutputFormat("Stopped job engine."); | ||
313 | // } | ||
314 | // else if (subCommand == "start") | ||
315 | // { | ||
316 | // Start(); | ||
317 | // MainConsole.Instance.OutputFormat("Started job engine."); | ||
318 | // } | ||
319 | // else if (subCommand == "status") | ||
320 | // { | ||
321 | // MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning); | ||
322 | // MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none"); | ||
323 | // MainConsole.Instance.OutputFormat( | ||
324 | // "Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a"); | ||
325 | // MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel); | ||
326 | // } | ||
327 | // | ||
328 | // else if (subCommand == "loglevel") | ||
329 | // { | ||
330 | // // int logLevel; | ||
331 | // int logLevel = int.Parse(args[3]); | ||
332 | // // if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel)) | ||
333 | // // { | ||
334 | // LogLevel = logLevel; | ||
335 | // MainConsole.Instance.OutputFormat("Set log level to {0}", LogLevel); | ||
336 | // // } | ||
337 | // } | ||
338 | // else | ||
339 | // { | ||
340 | // MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand); | ||
341 | // } | ||
342 | // } | ||
343 | } | ||
344 | } | ||
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index 04615a9..2ac1517 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs | |||
@@ -189,50 +189,203 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
189 | return Utils.StringToBytes(RewriteSOP(xml)); | 189 | return Utils.StringToBytes(RewriteSOP(xml)); |
190 | } | 190 | } |
191 | 191 | ||
192 | protected string RewriteSOP(string xml) | 192 | protected void TransformXml(XmlReader reader, XmlWriter writer) |
193 | { | 193 | { |
194 | XmlDocument doc = new XmlDocument(); | 194 | // m_log.DebugFormat("[HG ASSET MAPPER]: Transforming XML"); |
195 | doc.LoadXml(xml); | ||
196 | XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); | ||
197 | 195 | ||
198 | foreach (XmlNode sop in sops) | 196 | int sopDepth = -1; |
197 | UserAccount creator = null; | ||
198 | bool hasCreatorData = false; | ||
199 | |||
200 | while (reader.Read()) | ||
199 | { | 201 | { |
200 | UserAccount creator = null; | 202 | //Console.WriteLine("Depth: {0}", reader.Depth); |
201 | bool hasCreatorData = false; | 203 | |
202 | XmlNodeList nodes = sop.ChildNodes; | 204 | switch (reader.NodeType) |
203 | foreach (XmlNode node in nodes) | ||
204 | { | 205 | { |
205 | if (node.Name == "CreatorID") | 206 | case XmlNodeType.Attribute: |
207 | writer.WriteAttributeString(reader.Prefix, reader.Name, reader.NamespaceURI, reader.Value); | ||
208 | break; | ||
209 | |||
210 | case XmlNodeType.CDATA: | ||
211 | writer.WriteCData(reader.Value); | ||
212 | break; | ||
213 | |||
214 | case XmlNodeType.Comment: | ||
215 | writer.WriteComment(reader.Value); | ||
216 | break; | ||
217 | |||
218 | case XmlNodeType.DocumentType: | ||
219 | writer.WriteDocType(reader.Name, reader.Value, null, null); | ||
220 | break; | ||
221 | |||
222 | case XmlNodeType.Element: | ||
223 | // m_log.DebugFormat("Depth {0} at element {1}", reader.Depth, reader.Name); | ||
224 | |||
225 | writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); | ||
226 | |||
227 | if (reader.LocalName == "SceneObjectPart") | ||
206 | { | 228 | { |
207 | UUID uuid = UUID.Zero; | 229 | if (sopDepth < 0) |
208 | UUID.TryParse(node.InnerText, out uuid); | 230 | { |
209 | creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | 231 | sopDepth = reader.Depth; |
232 | // m_log.DebugFormat("[HG ASSET MAPPER]: Set sopDepth to {0}", sopDepth); | ||
233 | } | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | if (sopDepth >= 0 && reader.Depth == sopDepth + 1) | ||
238 | { | ||
239 | if (reader.Name == "CreatorID") | ||
240 | { | ||
241 | reader.Read(); | ||
242 | if (reader.NodeType == XmlNodeType.Element && reader.Name == "Guid" || reader.Name == "UUID") | ||
243 | { | ||
244 | reader.Read(); | ||
245 | |||
246 | if (reader.NodeType == XmlNodeType.Text) | ||
247 | { | ||
248 | UUID uuid = UUID.Zero; | ||
249 | UUID.TryParse(reader.Value, out uuid); | ||
250 | creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | ||
251 | writer.WriteElementString("UUID", reader.Value); | ||
252 | reader.Read(); | ||
253 | } | ||
254 | else | ||
255 | { | ||
256 | // If we unexpected run across mixed content in this node, still carry on | ||
257 | // transforming the subtree (this replicates earlier behaviour). | ||
258 | TransformXml(reader, writer); | ||
259 | } | ||
260 | } | ||
261 | else | ||
262 | { | ||
263 | // If we unexpected run across mixed content in this node, still carry on | ||
264 | // transforming the subtree (this replicates earlier behaviour). | ||
265 | TransformXml(reader, writer); | ||
266 | } | ||
267 | } | ||
268 | else if (reader.Name == "CreatorData") | ||
269 | { | ||
270 | reader.Read(); | ||
271 | if (reader.NodeType == XmlNodeType.Text) | ||
272 | { | ||
273 | hasCreatorData = true; | ||
274 | writer.WriteString(reader.Value); | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | // If we unexpected run across mixed content in this node, still carry on | ||
279 | // transforming the subtree (this replicates earlier behaviour). | ||
280 | TransformXml(reader, writer); | ||
281 | } | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | |||
286 | if (reader.IsEmptyElement) | ||
287 | { | ||
288 | // m_log.DebugFormat("[HG ASSET MAPPER]: Writing end for empty element {0}", reader.Name); | ||
289 | writer.WriteEndElement(); | ||
210 | } | 290 | } |
211 | if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) | ||
212 | hasCreatorData = true; | ||
213 | |||
214 | //if (node.Name == "OwnerID") | ||
215 | //{ | ||
216 | // UserAccount owner = GetUser(node.InnerText); | ||
217 | // if (owner != null) | ||
218 | // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; | ||
219 | //} | ||
220 | } | ||
221 | 291 | ||
222 | if (!hasCreatorData && creator != null) | 292 | break; |
223 | { | 293 | |
224 | XmlElement creatorData = doc.CreateElement("CreatorData"); | 294 | case XmlNodeType.EndElement: |
225 | creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName; | 295 | // m_log.DebugFormat("Depth {0} at EndElement", reader.Depth); |
226 | sop.AppendChild(creatorData); | 296 | if (sopDepth == reader.Depth) |
297 | { | ||
298 | if (!hasCreatorData && creator != null) | ||
299 | writer.WriteElementString(reader.Prefix, "CreatorData", reader.NamespaceURI, string.Format("{0};{1} {2}", m_HomeURI, creator.FirstName, creator.LastName)); | ||
300 | |||
301 | // m_log.DebugFormat("[HG ASSET MAPPER]: Reset sopDepth"); | ||
302 | sopDepth = -1; | ||
303 | creator = null; | ||
304 | hasCreatorData = false; | ||
305 | } | ||
306 | writer.WriteEndElement(); | ||
307 | break; | ||
308 | |||
309 | case XmlNodeType.EntityReference: | ||
310 | writer.WriteEntityRef(reader.Name); | ||
311 | break; | ||
312 | |||
313 | case XmlNodeType.ProcessingInstruction: | ||
314 | writer.WriteProcessingInstruction(reader.Name, reader.Value); | ||
315 | break; | ||
316 | |||
317 | case XmlNodeType.Text: | ||
318 | writer.WriteString(reader.Value); | ||
319 | break; | ||
320 | |||
321 | default: | ||
322 | m_log.WarnFormat("[HG ASSET MAPPER]: Unrecognized node in asset XML transform in {0}", m_scene.Name); | ||
323 | break; | ||
227 | } | 324 | } |
228 | } | 325 | } |
326 | } | ||
327 | |||
328 | protected string RewriteSOP(string xmlData) | ||
329 | { | ||
330 | // Console.WriteLine("Input XML [{0}]", xmlData); | ||
229 | 331 | ||
230 | using (StringWriter wr = new StringWriter()) | 332 | using (StringWriter sw = new StringWriter()) |
333 | using (XmlTextWriter writer = new XmlTextWriter(sw)) | ||
334 | using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) | ||
335 | using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) | ||
231 | { | 336 | { |
232 | doc.Save(wr); | 337 | TransformXml(reader, writer); |
233 | return wr.ToString(); | 338 | |
339 | writer.WriteEndDocument(); | ||
340 | |||
341 | // Console.WriteLine("Output: [{0}]", sw.ToString()); | ||
342 | |||
343 | return sw.ToString(); | ||
234 | } | 344 | } |
235 | 345 | ||
346 | // We are now taking the more complex streaming approach above because some assets can be very large | ||
347 | // and can trigger higher CPU use or possibly memory problems. | ||
348 | // XmlDocument doc = new XmlDocument(); | ||
349 | // doc.LoadXml(xml); | ||
350 | // XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); | ||
351 | // | ||
352 | // foreach (XmlNode sop in sops) | ||
353 | // { | ||
354 | // UserAccount creator = null; | ||
355 | // bool hasCreatorData = false; | ||
356 | // XmlNodeList nodes = sop.ChildNodes; | ||
357 | // foreach (XmlNode node in nodes) | ||
358 | // { | ||
359 | // if (node.Name == "CreatorID") | ||
360 | // { | ||
361 | // UUID uuid = UUID.Zero; | ||
362 | // UUID.TryParse(node.InnerText, out uuid); | ||
363 | // creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | ||
364 | // } | ||
365 | // if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) | ||
366 | // hasCreatorData = true; | ||
367 | // | ||
368 | // //if (node.Name == "OwnerID") | ||
369 | // //{ | ||
370 | // // UserAccount owner = GetUser(node.InnerText); | ||
371 | // // if (owner != null) | ||
372 | // // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; | ||
373 | // //} | ||
374 | // } | ||
375 | // | ||
376 | // if (!hasCreatorData && creator != null) | ||
377 | // { | ||
378 | // XmlElement creatorData = doc.CreateElement("CreatorData"); | ||
379 | // creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName; | ||
380 | // sop.AppendChild(creatorData); | ||
381 | // } | ||
382 | // } | ||
383 | // | ||
384 | // using (StringWriter wr = new StringWriter()) | ||
385 | // { | ||
386 | // doc.Save(wr); | ||
387 | // return wr.ToString(); | ||
388 | // } | ||
236 | } | 389 | } |
237 | 390 | ||
238 | // TODO: unused | 391 | // TODO: unused |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs new file mode 100644 index 0000000..779da43 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Xml; | ||
30 | using NUnit.Framework; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | ||
34 | using OpenSim.Region.Framework.Scenes; | ||
35 | using OpenSim.Services.Interfaces; | ||
36 | using OpenSim.Tests.Common; | ||
37 | |||
38 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | ||
39 | { | ||
40 | [TestFixture] | ||
41 | public class HGAssetMapperTests : OpenSimTestCase | ||
42 | { | ||
43 | [Test] | ||
44 | public void TestPostAssetRewrite() | ||
45 | { | ||
46 | TestHelpers.InMethod(); | ||
47 | // TestHelpers.EnableLogging(); | ||
48 | |||
49 | string homeUrl = "http://hg.HomeTestPostAssetRewriteGrid.com"; | ||
50 | string foreignUrl = "http://hg.ForeignTestPostAssetRewriteGrid.com"; | ||
51 | UUID assetId = TestHelpers.ParseTail(0x1); | ||
52 | UUID userId = TestHelpers.ParseTail(0x10); | ||
53 | string userFirstName = "TestPostAsset"; | ||
54 | string userLastName = "Rewrite"; | ||
55 | int soPartsCount = 3; | ||
56 | |||
57 | Scene scene = new SceneHelpers().SetupScene(); | ||
58 | HGAssetMapper hgam = new HGAssetMapper(scene, homeUrl); | ||
59 | UserAccount ua | ||
60 | = UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "password"); | ||
61 | |||
62 | //AssetBase ncAssetSet = AssetHelpers.CreateNotecardAsset(assetId, "TestPostAssetRewriteNotecard"); | ||
63 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(soPartsCount, ua.PrincipalID); | ||
64 | AssetBase ncAssetSet = AssetHelpers.CreateAsset(assetId, so); | ||
65 | ncAssetSet.CreatorID = foreignUrl; | ||
66 | hgam.PostAsset(foreignUrl, ncAssetSet); | ||
67 | |||
68 | AssetBase ncAssetGet = scene.AssetService.Get(assetId.ToString()); | ||
69 | Assert.AreEqual(foreignUrl, ncAssetGet.CreatorID); | ||
70 | string xmlData = Utils.BytesToString(ncAssetGet.Data); | ||
71 | XmlDocument ncAssetGetXmlDoc = new XmlDocument(); | ||
72 | ncAssetGetXmlDoc.LoadXml(xmlData); | ||
73 | XmlNodeList creatorDataNodes = ncAssetGetXmlDoc.GetElementsByTagName("CreatorData"); | ||
74 | |||
75 | Assert.AreEqual(soPartsCount, creatorDataNodes.Count); | ||
76 | //Console.WriteLine("creatorDataNodes {0}", creatorDataNodes.Count); | ||
77 | |||
78 | foreach (XmlNode creatorDataNode in creatorDataNodes) | ||
79 | { | ||
80 | Assert.AreEqual( | ||
81 | string.Format("{0};{1} {2}", homeUrl, ua.FirstName, ua.LastName), creatorDataNode.InnerText); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index 80b9c0a..c64ab44 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | |||
@@ -44,7 +44,6 @@ using OpenSim.Region.Framework.Scenes; | |||
44 | using OpenSim.Region.Framework.Scenes.Serialization; | 44 | using OpenSim.Region.Framework.Scenes.Serialization; |
45 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | 47 | ||
49 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | 48 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests |
50 | { | 49 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs index a70261e..3abacbd 100644 --- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs | |||
@@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.Framework | |||
67 | m_timer.Elapsed += ProcessQueue; | 67 | m_timer.Elapsed += ProcessQueue; |
68 | m_timer.Start(); | 68 | m_timer.Start(); |
69 | 69 | ||
70 | //Watchdog.StartThread( | 70 | //WorkManager.StartThread( |
71 | // ProcessQueue, | 71 | // ProcessQueue, |
72 | // "GridServiceRequestThread", | 72 | // "GridServiceRequestThread", |
73 | // ThreadPriority.BelowNormal, | 73 | // ThreadPriority.BelowNormal, |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs index 9d36aa5..4e3b7e5 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs | |||
@@ -32,7 +32,6 @@ using OpenMetaverse; | |||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.CoreModules.Framework.UserManagement; | 33 | using OpenSim.Region.CoreModules.Framework.UserManagement; |
34 | using OpenSim.Tests.Common; | 34 | using OpenSim.Tests.Common; |
35 | using OpenSim.Tests.Common.Mock; | ||
36 | 35 | ||
37 | namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests | 36 | namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests |
38 | { | 37 | { |
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs index e812d81..4d8b591 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs | |||
@@ -41,7 +41,6 @@ using OpenSim.Framework; | |||
41 | using OpenSim.Region.CoreModules.Scripting.HttpRequest; | 41 | using OpenSim.Region.CoreModules.Scripting.HttpRequest; |
42 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
43 | using OpenSim.Tests.Common; | 43 | using OpenSim.Tests.Common; |
44 | using OpenSim.Tests.Common.Mock; | ||
45 | 44 | ||
46 | namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests | 45 | namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests |
47 | { | 46 | { |
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 7119137..ed255bf 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs | |||
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.Scripting.VectorRender; | |||
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Region.Framework.Scenes.Serialization; | 41 | using OpenSim.Region.Framework.Scenes.Serialization; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests | 44 | namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests |
46 | { | 45 | { |
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index d7ea906..af3700b 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | |||
@@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC | |||
658 | public void Process() | 658 | public void Process() |
659 | { | 659 | { |
660 | _finished = false; | 660 | _finished = false; |
661 | Watchdog.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false); | 661 | WorkManager.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false); |
662 | } | 662 | } |
663 | 663 | ||
664 | /* | 664 | /* |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 38862ca..7fcfc74 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs | |||
@@ -69,6 +69,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
69 | get { return "HGAssetBroker"; } | 69 | get { return "HGAssetBroker"; } |
70 | } | 70 | } |
71 | 71 | ||
72 | public HGAssetBroker() {} | ||
73 | |||
74 | public HGAssetBroker(IConfigSource config) | ||
75 | { | ||
76 | Initialise(config); | ||
77 | } | ||
78 | |||
72 | public void Initialise(IConfigSource source) | 79 | public void Initialise(IConfigSource source) |
73 | { | 80 | { |
74 | IConfig moduleConfig = source.Configs["Modules"]; | 81 | IConfig moduleConfig = source.Configs["Modules"]; |
@@ -288,7 +295,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
288 | 295 | ||
289 | if (asset != null) | 296 | if (asset != null) |
290 | { | 297 | { |
291 | Util.FireAndForget(delegate { handler(id, sender, asset); }); | 298 | Util.FireAndForget(delegate { handler(id, sender, asset); }, null, "HGAssetBroker.GotFromCache"); |
292 | return true; | 299 | return true; |
293 | } | 300 | } |
294 | 301 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 97b7559..5f34450 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs | |||
@@ -236,7 +236,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
236 | 236 | ||
237 | if (asset != null) | 237 | if (asset != null) |
238 | { | 238 | { |
239 | Util.FireAndForget(delegate { handler(id, sender, asset); }); | 239 | Util.FireAndForget( |
240 | o => handler(id, sender, asset), null, "LocalAssetServiceConnector.GotFromCacheCallback"); | ||
240 | return true; | 241 | return true; |
241 | } | 242 | } |
242 | } | 243 | } |
@@ -249,7 +250,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
249 | // if (null == a) | 250 | // if (null == a) |
250 | // m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not asynchronously find asset with id {0}", id); | 251 | // m_log.WarnFormat("[LOCAL ASSET SERVICES CONNECTOR]: Could not asynchronously find asset with id {0}", id); |
251 | 252 | ||
252 | Util.FireAndForget(delegate { handler(assetID, s, a); }); | 253 | Util.FireAndForget( |
254 | o => handler(assetID, s, a), null, "LocalAssetServiceConnector.GotFromServiceCallback"); | ||
253 | }); | 255 | }); |
254 | } | 256 | } |
255 | 257 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 8e995db..4661c21 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -198,8 +198,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
198 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) | 198 | public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) |
199 | { | 199 | { |
200 | GridRegion region = null; | 200 | GridRegion region = null; |
201 | uint regionX = Util.WorldToRegionLoc((uint)x); | 201 | // uint regionX = Util.WorldToRegionLoc((uint)x); |
202 | uint regionY = Util.WorldToRegionLoc((uint)y); | 202 | // uint regionY = Util.WorldToRegionLoc((uint)y); |
203 | 203 | ||
204 | // First see if it's a neighbour, even if it isn't on this sim. | 204 | // First see if it's a neighbour, even if it isn't on this sim. |
205 | // Neighbour data is cached in memory, so this is fast | 205 | // Neighbour data is cached in memory, so this is fast |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 470ef02..cbe0e37 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs | |||
@@ -184,12 +184,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
184 | // Protect ourselves against the caller subsequently modifying the items list | 184 | // Protect ourselves against the caller subsequently modifying the items list |
185 | List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); | 185 | List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); |
186 | 186 | ||
187 | Watchdog.RunInThread(delegate | 187 | WorkManager.RunInThread(delegate |
188 | { | 188 | { |
189 | foreach (InventoryItemBase item in items) | 189 | foreach (InventoryItemBase item in items) |
190 | if (!string.IsNullOrEmpty(item.CreatorData)) | 190 | if (!string.IsNullOrEmpty(item.CreatorData)) |
191 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); | 191 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); |
192 | }, string.Format("GetFolderContent (user {0}, folder {1})", userID, folderID), null); | 192 | }, null, string.Format("GetFolderContent (user {0}, folder {1})", userID, folderID)); |
193 | } | 193 | } |
194 | 194 | ||
195 | return invCol; | 195 | return invCol; |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 3e0c9f3..9c6706f 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -372,7 +372,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
372 | // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so | 372 | // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so |
373 | // that users can enter the scene. If we allow the scripts to start in the loop above | 373 | // that users can enter the scene. If we allow the scripts to start in the loop above |
374 | // then they significantly increase the time until the OAR finishes loading. | 374 | // then they significantly increase the time until the OAR finishes loading. |
375 | Watchdog.RunInThread(o => | 375 | WorkManager.RunInThread(o => |
376 | { | 376 | { |
377 | Thread.Sleep(15000); | 377 | Thread.Sleep(15000); |
378 | m_log.Info("[ARCHIVER]: Starting scripts in scene objects"); | 378 | m_log.Info("[ARCHIVER]: Starting scripts in scene objects"); |
@@ -387,7 +387,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
387 | 387 | ||
388 | sceneContext.SceneObjects.Clear(); | 388 | sceneContext.SceneObjects.Clear(); |
389 | } | 389 | } |
390 | }, string.Format("ReadArchiveStartScripts (request {0})", m_requestId), null); | 390 | }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId)); |
391 | 391 | ||
392 | m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); | 392 | m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); |
393 | 393 | ||
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index 924b999..b7d7c26 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs | |||
@@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
200 | m_rootScene.AssetService, m_rootScene.UserAccountService, | 200 | m_rootScene.AssetService, m_rootScene.UserAccountService, |
201 | m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); | 201 | m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); |
202 | 202 | ||
203 | Watchdog.RunInThread(o => ar.Execute(), "Archive Assets Request", null); | 203 | WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request"); |
204 | 204 | ||
205 | // CloseArchive() will be called from ReceivedAllAssets() | 205 | // CloseArchive() will be called from ReceivedAllAssets() |
206 | } | 206 | } |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index ec39bc0..4d99a6e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs | |||
@@ -227,7 +227,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
227 | finally | 227 | finally |
228 | { | 228 | { |
229 | if (timedOut) | 229 | if (timedOut) |
230 | Watchdog.RunInThread(PerformAssetsRequestCallback, "Archive Assets Request Callback", true); | 230 | WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback"); |
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
@@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
296 | 296 | ||
297 | // We want to stop using the asset cache thread asap | 297 | // We want to stop using the asset cache thread asap |
298 | // as we now need to do the work of producing the rest of the archive | 298 | // as we now need to do the work of producing the rest of the archive |
299 | Watchdog.RunInThread(PerformAssetsRequestCallback, "Archive Assets Request Callback", false); | 299 | WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback"); |
300 | } | 300 | } |
301 | else | 301 | else |
302 | { | 302 | { |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index b31257d..9f197f5 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.Framework.Scenes; | |||
45 | using OpenSim.Region.Framework.Scenes.Serialization; | 45 | using OpenSim.Region.Framework.Scenes.Serialization; |
46 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; | 46 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; | 48 | using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; |
50 | using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; | 49 | using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; |
51 | using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; | 50 | using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; |
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs index 6d0253d..4ed67f3 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/LandManagementModuleTests.cs | |||
@@ -31,7 +31,6 @@ using OpenMetaverse; | |||
31 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
32 | using OpenSim.Region.Framework.Scenes; | 32 | using OpenSim.Region.Framework.Scenes; |
33 | using OpenSim.Tests.Common; | 33 | using OpenSim.Tests.Common; |
34 | using OpenSim.Tests.Common.Mock; | ||
35 | 34 | ||
36 | namespace OpenSim.Region.CoreModules.World.Land.Tests | 35 | namespace OpenSim.Region.CoreModules.World.Land.Tests |
37 | { | 36 | { |
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index 0945b43..949acb6 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs | |||
@@ -36,7 +36,6 @@ using OpenSim.Framework; | |||
36 | using OpenSim.Region.Framework.Interfaces; | 36 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | ||
40 | 39 | ||
41 | namespace OpenSim.Region.CoreModules.World.Land.Tests | 40 | namespace OpenSim.Region.CoreModules.World.Land.Tests |
42 | { | 41 | { |
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index 03a96a4..ee57aed 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs | |||
@@ -39,7 +39,6 @@ using OpenSim.Region.CoreModules.World.Media.Moap; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.Framework.Scenes.Serialization; | 40 | using OpenSim.Region.Framework.Scenes.Serialization; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests | 43 | namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests |
45 | { | 44 | { |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 78fbefe..767f75f 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -381,7 +381,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
381 | 381 | ||
382 | // m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); | 382 | // m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); |
383 | 383 | ||
384 | Watchdog.StartThread( | 384 | WorkManager.StartThread( |
385 | process, | 385 | process, |
386 | string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), | 386 | string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), |
387 | ThreadPriority.BelowNormal, | 387 | ThreadPriority.BelowNormal, |
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 5d07a5f..1ebef90 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs | |||
@@ -98,6 +98,8 @@ namespace OpenSim.Region.Framework.Interfaces | |||
98 | void Cross(SceneObjectGroup sog, Vector3 position, bool silent); | 98 | void Cross(SceneObjectGroup sog, Vector3 position, bool silent); |
99 | 99 | ||
100 | ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); | 100 | ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); |
101 | |||
102 | bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition); | ||
101 | } | 103 | } |
102 | 104 | ||
103 | public interface IUserAgentVerificationModule | 105 | public interface IUserAgentVerificationModule |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0399a52..f7c12d6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -6,7 +6,7 @@ | |||
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyrightD | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
@@ -360,19 +360,41 @@ namespace OpenSim.Region.Framework.Scenes | |||
360 | public uint MaintenanceRun { get; private set; } | 360 | public uint MaintenanceRun { get; private set; } |
361 | 361 | ||
362 | /// <summary> | 362 | /// <summary> |
363 | /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we | 363 | /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we |
364 | /// will sleep for the remaining period. | 364 | /// will sleep for the remaining period. |
365 | /// </summary> | 365 | /// </summary> |
366 | /// <remarks> | 366 | /// <remarks> |
367 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations | 367 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations |
368 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). | 368 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). |
369 | /// </remarks> | 369 | /// </remarks> |
370 | public float MinFrameTime { get; private set; } | 370 | public int MinFrameTicks |
371 | { | ||
372 | get { return m_minFrameTicks; } | ||
373 | private set | ||
374 | { | ||
375 | m_minFrameTicks = value; | ||
376 | MinFrameSeconds = (float)m_minFrameTicks / 1000; | ||
377 | } | ||
378 | } | ||
379 | private int m_minFrameTicks; | ||
371 | 380 | ||
372 | /// <summary> | 381 | /// <summary> |
373 | /// The minimum length of time in seconds that will be taken for a maintenance run. | 382 | /// The minimum length of time in seconds that will be taken for a scene frame. |
374 | /// </summary> | 383 | /// </summary> |
375 | public float MinMaintenanceTime { get; private set; } | 384 | /// <remarks> |
385 | /// Always derived from MinFrameTicks. | ||
386 | /// </remarks> | ||
387 | public float MinFrameSeconds { get; private set; } | ||
388 | |||
389 | /// <summary> | ||
390 | /// The minimum length of time in milliseconds that will be taken for a scene frame. If the frame takes less time then we | ||
391 | /// will sleep for the remaining period. | ||
392 | /// </summary> | ||
393 | /// <remarks> | ||
394 | /// One can tweak this number to experiment. One current effect of reducing it is to make avatar animations | ||
395 | /// occur too quickly (viewer 1) or with even more slide (viewer 2). | ||
396 | /// </remarks> | ||
397 | public int MinMaintenanceTicks { get; set; } | ||
376 | 398 | ||
377 | private int m_update_physics = 1; | 399 | private int m_update_physics = 1; |
378 | private int m_update_entitymovement = 1; | 400 | private int m_update_entitymovement = 1; |
@@ -412,8 +434,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
412 | /// asynchronously from the update loop. | 434 | /// asynchronously from the update loop. |
413 | /// </summary> | 435 | /// </summary> |
414 | private bool m_cleaningTemps = false; | 436 | private bool m_cleaningTemps = false; |
437 | |||
438 | /// <summary> | ||
439 | /// Used to control main scene thread looping time when not updating via timer. | ||
440 | /// </summary> | ||
441 | private ManualResetEvent m_updateWaitEvent = new ManualResetEvent(false); | ||
415 | 442 | ||
416 | // private Object m_heartbeatLock = new Object(); | 443 | /// <summary> |
444 | /// Used to control maintenance thread runs. | ||
445 | /// </summary> | ||
446 | private ManualResetEvent m_maintenanceWaitEvent = new ManualResetEvent(false); | ||
417 | 447 | ||
418 | // TODO: Possibly stop other classes being able to manipulate this directly. | 448 | // TODO: Possibly stop other classes being able to manipulate this directly. |
419 | private SceneGraph m_sceneGraph; | 449 | private SceneGraph m_sceneGraph; |
@@ -782,8 +812,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
782 | : this(regInfo, physicsScene) | 812 | : this(regInfo, physicsScene) |
783 | { | 813 | { |
784 | m_config = config; | 814 | m_config = config; |
785 | MinFrameTime = 0.089f; | 815 | MinFrameTicks = 89; |
786 | MinMaintenanceTime = 1; | 816 | MinMaintenanceTicks = 1000; |
787 | SeeIntoRegion = true; | 817 | SeeIntoRegion = true; |
788 | 818 | ||
789 | Random random = new Random(); | 819 | Random random = new Random(); |
@@ -1005,7 +1035,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1005 | } | 1035 | } |
1006 | } | 1036 | } |
1007 | 1037 | ||
1008 | MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime); | 1038 | if (startupConfig.Contains("MinFrameTime")) |
1039 | MinFrameTicks = (int)(startupConfig.GetFloat("MinFrameTime") * 1000); | ||
1040 | |||
1009 | m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); | 1041 | m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup); |
1010 | m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); | 1042 | m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations); |
1011 | m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); | 1043 | m_update_entitymovement = startupConfig.GetInt( "UpdateEntityMovementEveryNFrames", m_update_entitymovement); |
@@ -1396,7 +1428,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1396 | } | 1428 | } |
1397 | 1429 | ||
1398 | m_heartbeatThread | 1430 | m_heartbeatThread |
1399 | = Watchdog.StartThread( | 1431 | = WorkManager.StartThread( |
1400 | Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); | 1432 | Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false); |
1401 | 1433 | ||
1402 | StartScripts(); | 1434 | StartScripts(); |
@@ -1437,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1437 | // alarms for scenes with many objects. | 1469 | // alarms for scenes with many objects. |
1438 | Update(1); | 1470 | Update(1); |
1439 | 1471 | ||
1440 | Watchdog.StartThread( | 1472 | WorkManager.StartThread( |
1441 | Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); | 1473 | Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); |
1442 | 1474 | ||
1443 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; | 1475 | Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; |
@@ -1445,13 +1477,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1445 | 1477 | ||
1446 | if (UpdateOnTimer) | 1478 | if (UpdateOnTimer) |
1447 | { | 1479 | { |
1448 | m_sceneUpdateTimer = new Timer(MinFrameTime * 1000); | 1480 | m_sceneUpdateTimer = new Timer(MinFrameTicks); |
1449 | m_sceneUpdateTimer.AutoReset = true; | 1481 | m_sceneUpdateTimer.AutoReset = true; |
1450 | m_sceneUpdateTimer.Elapsed += Update; | 1482 | m_sceneUpdateTimer.Elapsed += Update; |
1451 | m_sceneUpdateTimer.Start(); | 1483 | m_sceneUpdateTimer.Start(); |
1452 | } | 1484 | } |
1453 | else | 1485 | else |
1454 | { | 1486 | { |
1487 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
1455 | Update(-1); | 1488 | Update(-1); |
1456 | Watchdog.RemoveThread(); | 1489 | Watchdog.RemoveThread(); |
1457 | m_isRunning = false; | 1490 | m_isRunning = false; |
@@ -1535,10 +1568,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1535 | tmpMS = Util.EnvironmentTickCount(); | 1568 | tmpMS = Util.EnvironmentTickCount(); |
1536 | m_cleaningTemps = true; | 1569 | m_cleaningTemps = true; |
1537 | 1570 | ||
1538 | Watchdog.RunInThread( | 1571 | WorkManager.RunInThread( |
1539 | delegate { CleanTempObjects(); m_cleaningTemps = false; }, | 1572 | delegate { CleanTempObjects(); m_cleaningTemps = false; }, |
1540 | string.Format("CleanTempObjects ({0})", Name), | 1573 | null, |
1541 | null); | 1574 | string.Format("CleanTempObjects ({0})", Name)); |
1542 | 1575 | ||
1543 | tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1576 | tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); |
1544 | } | 1577 | } |
@@ -1548,19 +1581,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1548 | previousMaintenanceTick = m_lastMaintenanceTick; | 1581 | previousMaintenanceTick = m_lastMaintenanceTick; |
1549 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); | 1582 | m_lastMaintenanceTick = Util.EnvironmentTickCount(); |
1550 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); | 1583 | runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); |
1551 | runtc = (int)(MinMaintenanceTime * 1000) - runtc; | 1584 | runtc = MinMaintenanceTicks - runtc; |
1552 | 1585 | ||
1553 | if (runtc > 0) | 1586 | if (runtc > 0) |
1554 | Thread.Sleep(runtc); | 1587 | m_maintenanceWaitEvent.WaitOne(runtc); |
1555 | 1588 | ||
1556 | // Optionally warn if a frame takes double the amount of time that it should. | 1589 | // Optionally warn if a frame takes double the amount of time that it should. |
1557 | if (DebugUpdates | 1590 | if (DebugUpdates |
1558 | && Util.EnvironmentTickCountSubtract( | 1591 | && Util.EnvironmentTickCountSubtract( |
1559 | m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) | 1592 | m_lastMaintenanceTick, previousMaintenanceTick) > MinMaintenanceTicks * 2) |
1560 | m_log.WarnFormat( | 1593 | m_log.WarnFormat( |
1561 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", | 1594 | "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", |
1562 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), | 1595 | Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), |
1563 | MinMaintenanceTime * 1000, | 1596 | MinMaintenanceTicks, |
1564 | RegionInfo.RegionName); | 1597 | RegionInfo.RegionName); |
1565 | } | 1598 | } |
1566 | } | 1599 | } |
@@ -1612,7 +1645,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1612 | if (Frame % m_update_physics == 0) | 1645 | if (Frame % m_update_physics == 0) |
1613 | { | 1646 | { |
1614 | if (PhysicsEnabled) | 1647 | if (PhysicsEnabled) |
1615 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime); | 1648 | physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameSeconds); |
1616 | 1649 | ||
1617 | if (SynchronizeScene != null) | 1650 | if (SynchronizeScene != null) |
1618 | SynchronizeScene(this); | 1651 | SynchronizeScene(this); |
@@ -1710,18 +1743,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1710 | { | 1743 | { |
1711 | Watchdog.UpdateThread(); | 1744 | Watchdog.UpdateThread(); |
1712 | 1745 | ||
1713 | tmpMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(), m_lastFrameTick); | 1746 | spareMS = MinFrameTicks - Util.EnvironmentTickCountSubtract(m_lastFrameTick); |
1714 | tmpMS = (int)(MinFrameTime * 1000) - tmpMS; | ||
1715 | 1747 | ||
1716 | if (tmpMS > 0) | 1748 | if (spareMS > 0) |
1717 | { | 1749 | m_updateWaitEvent.WaitOne(spareMS); |
1718 | spareMS = tmpMS; | 1750 | else |
1719 | Thread.Sleep(tmpMS); | 1751 | spareMS = 0; |
1720 | } | ||
1721 | } | 1752 | } |
1722 | else | 1753 | else |
1723 | { | 1754 | { |
1724 | spareMS = Math.Max(0, (int)(MinFrameTime * 1000) - physicsMS2 - agentMS - physicsMS -otherMS); | 1755 | spareMS = Math.Max(0, MinFrameTicks - physicsMS2 - agentMS - physicsMS - otherMS); |
1725 | } | 1756 | } |
1726 | 1757 | ||
1727 | previousFrameTick = m_lastFrameTick; | 1758 | previousFrameTick = m_lastFrameTick; |
@@ -1744,11 +1775,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1744 | // Optionally warn if a frame takes double the amount of time that it should. | 1775 | // Optionally warn if a frame takes double the amount of time that it should. |
1745 | if (DebugUpdates | 1776 | if (DebugUpdates |
1746 | && Util.EnvironmentTickCountSubtract( | 1777 | && Util.EnvironmentTickCountSubtract( |
1747 | m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) | 1778 | m_lastFrameTick, previousFrameTick) > MinFrameTicks * 2) |
1748 | m_log.WarnFormat( | 1779 | m_log.WarnFormat( |
1749 | "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", | 1780 | "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", |
1750 | Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), | 1781 | Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick), |
1751 | MinFrameTime * 1000, | 1782 | MinFrameTicks, |
1752 | RegionInfo.RegionName); | 1783 | RegionInfo.RegionName); |
1753 | } | 1784 | } |
1754 | 1785 | ||
@@ -1812,7 +1843,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1812 | if (!m_backingup) | 1843 | if (!m_backingup) |
1813 | { | 1844 | { |
1814 | m_backingup = true; | 1845 | m_backingup = true; |
1815 | Watchdog.RunInThread(o => Backup(false), string.Format("BackupWaitCallback ({0})", Name), null); | 1846 | WorkManager.RunInThread(o => Backup(false), null, string.Format("BackupWaitCallback ({0})", Name)); |
1816 | } | 1847 | } |
1817 | } | 1848 | } |
1818 | 1849 | ||
@@ -2592,48 +2623,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2592 | return false; | 2623 | return false; |
2593 | } | 2624 | } |
2594 | 2625 | ||
2595 | // If the user is banned, we won't let any of their objects | 2626 | if (!EntityTransferModule.HandleIncomingSceneObject(newObject, newPosition)) |
2596 | // enter. Period. | 2627 | return false; |
2597 | // | ||
2598 | if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID)) | ||
2599 | { | ||
2600 | m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID); | ||
2601 | return false; | ||
2602 | } | ||
2603 | |||
2604 | if (newPosition != Vector3.Zero) | ||
2605 | newObject.RootPart.GroupPosition = newPosition; | ||
2606 | |||
2607 | if (!AddSceneObject(newObject)) | ||
2608 | { | ||
2609 | m_log.DebugFormat( | ||
2610 | "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName); | ||
2611 | return false; | ||
2612 | } | ||
2613 | |||
2614 | if (!newObject.IsAttachment) | ||
2615 | { | ||
2616 | // FIXME: It would be better to never add the scene object at all rather than add it and then delete | ||
2617 | // it | ||
2618 | if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition)) | ||
2619 | { | ||
2620 | // Deny non attachments based on parcel settings | ||
2621 | // | ||
2622 | m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); | ||
2623 | |||
2624 | DeleteSceneObject(newObject, false); | ||
2625 | |||
2626 | return false; | ||
2627 | } | ||
2628 | |||
2629 | // For attachments, we need to wait until the agent is root | ||
2630 | // before we restart the scripts, or else some functions won't work. | ||
2631 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); | ||
2632 | newObject.ResumeScripts(); | ||
2633 | |||
2634 | if (newObject.RootPart.KeyframeMotion != null) | ||
2635 | newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject); | ||
2636 | } | ||
2637 | 2628 | ||
2638 | // Do this as late as possible so that listeners have full access to the incoming object | 2629 | // Do this as late as possible so that listeners have full access to the incoming object |
2639 | EventManager.TriggerOnIncomingSceneObject(newObject); | 2630 | EventManager.TriggerOnIncomingSceneObject(newObject); |
@@ -2702,16 +2693,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2702 | return true; | 2693 | return true; |
2703 | } | 2694 | } |
2704 | 2695 | ||
2705 | private int GetStateSource(SceneObjectGroup sog) | ||
2706 | { | ||
2707 | ScenePresence sp = GetScenePresence(sog.OwnerID); | ||
2708 | |||
2709 | if (sp != null) | ||
2710 | return sp.GetStateSource(); | ||
2711 | |||
2712 | return 2; // StateSource.PrimCrossing | ||
2713 | } | ||
2714 | |||
2715 | #endregion | 2696 | #endregion |
2716 | 2697 | ||
2717 | #region Add/Remove Avatar Methods | 2698 | #region Add/Remove Avatar Methods |
@@ -2758,29 +2739,41 @@ namespace OpenSim.Region.Framework.Scenes | |||
2758 | m_log.DebugFormat( | 2739 | m_log.DebugFormat( |
2759 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", | 2740 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", |
2760 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); | 2741 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); |
2761 | 2742 | ||
2743 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | ||
2744 | |||
2745 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | ||
2746 | // client is for a root or child agent. | ||
2747 | // We must also set this before adding the client to the client manager so that an exception later on | ||
2748 | // does not leave a client manager entry without the scene agent set, which will cause other code | ||
2749 | // to fail since any entry in the client manager should have a ScenePresence | ||
2750 | // | ||
2751 | // XXX: This may be better set for a new client before that client is added to the client manager. | ||
2752 | // But need to know what happens in the case where a ScenePresence is already present (and if this | ||
2753 | // actually occurs). | ||
2754 | client.SceneAgent = sp; | ||
2755 | |||
2762 | m_clientManager.Add(client); | 2756 | m_clientManager.Add(client); |
2763 | SubscribeToClientEvents(client); | 2757 | SubscribeToClientEvents(client); |
2764 | |||
2765 | sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); | ||
2766 | m_eventManager.TriggerOnNewPresence(sp); | 2758 | m_eventManager.TriggerOnNewPresence(sp); |
2767 | 2759 | ||
2768 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; | 2760 | sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags; |
2769 | } | 2761 | } |
2770 | else | 2762 | else |
2771 | { | 2763 | { |
2764 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | ||
2765 | // client is for a root or child agent. | ||
2766 | // XXX: This may be better set for a new client before that client is added to the client manager. | ||
2767 | // But need to know what happens in the case where a ScenePresence is already present (and if this | ||
2768 | // actually occurs). | ||
2769 | client.SceneAgent = sp; | ||
2770 | |||
2772 | m_log.WarnFormat( | 2771 | m_log.WarnFormat( |
2773 | "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", | 2772 | "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", |
2774 | sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); | 2773 | sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); |
2774 | |||
2775 | reallyNew = false; | 2775 | reallyNew = false; |
2776 | } | 2776 | } |
2777 | |||
2778 | // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the | ||
2779 | // client is for a root or child agent. | ||
2780 | // XXX: This may be better set for a new client before that client is added to the client manager. | ||
2781 | // But need to know what happens in the case where a ScenePresence is already present (and if this | ||
2782 | // actually occurs). | ||
2783 | client.SceneAgent = sp; | ||
2784 | 2777 | ||
2785 | // This is currently also being done earlier in NewUserConnection for real users to see if this | 2778 | // This is currently also being done earlier in NewUserConnection for real users to see if this |
2786 | // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other | 2779 | // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other |
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index bfa3b9a..9db5309 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | |||
@@ -226,7 +226,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
226 | // We must take a copy here since handle is acts like a reference when used in an iterator. | 226 | // We must take a copy here since handle is acts like a reference when used in an iterator. |
227 | // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. | 227 | // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. |
228 | ulong handleCopy = handle; | 228 | ulong handleCopy = handle; |
229 | Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); | 229 | Util.FireAndForget( |
230 | o => SendCloseChildAgent(agentID, handleCopy, auth_code), | ||
231 | null, | ||
232 | "SceneCommunicationService.SendCloseChildAgentConnections"); | ||
230 | } | 233 | } |
231 | } | 234 | } |
232 | 235 | ||
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 87063c6..5a35aff 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1228,10 +1228,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1228 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. | 1228 | // viewers without (e.g. v1 viewers) will not, so we still need to make this call. |
1229 | if (Scene.AttachmentsModule != null) | 1229 | if (Scene.AttachmentsModule != null) |
1230 | { | 1230 | { |
1231 | Util.FireAndForget(o => | 1231 | WorkManager.RunJob( |
1232 | { | 1232 | "RezAttachments", |
1233 | Scene.AttachmentsModule.RezAttachments(this); | 1233 | o => Scene.AttachmentsModule.RezAttachments(this), |
1234 | }); | 1234 | null, |
1235 | string.Format("Rez attachments for {0} in {1}", Name, Scene.Name)); | ||
1235 | } | 1236 | } |
1236 | } | 1237 | } |
1237 | else | 1238 | else |
@@ -1241,11 +1242,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1241 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | 1242 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are |
1242 | // not transporting the required data. | 1243 | // not transporting the required data. |
1243 | // | 1244 | // |
1244 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1245 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1246 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1247 | // not transporting the required data. | ||
1248 | // | ||
1249 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | 1245 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of |
1250 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | 1246 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here |
1251 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | 1247 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. |
@@ -1254,23 +1250,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
1254 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | 1250 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing |
1255 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | 1251 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the |
1256 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | 1252 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. |
1257 | // | ||
1258 | // One cannot simply iterate over attachments in a fire and forget thread because this would no longer | ||
1259 | // be locked, allowing race conditions if other code changes the attachments list. | ||
1260 | List<SceneObjectGroup> attachments = GetAttachments(); | 1253 | List<SceneObjectGroup> attachments = GetAttachments(); |
1261 | 1254 | ||
1262 | if (attachments.Count > 0) | 1255 | if (attachments.Count > 0) |
1263 | { | 1256 | { |
1264 | m_log.DebugFormat( | 1257 | WorkManager.RunJob( |
1265 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | 1258 | "StartAttachmentScripts", |
1266 | 1259 | o => RestartAttachmentScripts(attachments), | |
1267 | // Resume scripts | 1260 | null, |
1268 | foreach (SceneObjectGroup sog in attachments) | 1261 | string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name), |
1269 | { | 1262 | true); |
1270 | sog.ScheduleGroupForFullUpdate(); | ||
1271 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | ||
1272 | sog.ResumeScripts(); | ||
1273 | } | ||
1274 | } | 1263 | } |
1275 | } | 1264 | } |
1276 | 1265 | ||
@@ -1294,6 +1283,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1294 | return true; | 1283 | return true; |
1295 | } | 1284 | } |
1296 | 1285 | ||
1286 | private void RestartAttachmentScripts(List<SceneObjectGroup> attachments) | ||
1287 | { | ||
1288 | m_log.DebugFormat( | ||
1289 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1290 | |||
1291 | // Resume scripts | ||
1292 | foreach (SceneObjectGroup sog in attachments) | ||
1293 | { | ||
1294 | sog.ScheduleGroupForFullUpdate(); | ||
1295 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | ||
1296 | sog.ResumeScripts(); | ||
1297 | } | ||
1298 | } | ||
1299 | |||
1297 | private static bool IsRealLogin(TeleportFlags teleportFlags) | 1300 | private static bool IsRealLogin(TeleportFlags teleportFlags) |
1298 | { | 1301 | { |
1299 | return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0); | 1302 | return ((teleportFlags & TeleportFlags.ViaLogin) != 0) && ((teleportFlags & TeleportFlags.ViaHGLogin) == 0); |
@@ -1326,7 +1329,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1326 | 1329 | ||
1327 | UseFakeGroupTitle = false; | 1330 | UseFakeGroupTitle = false; |
1328 | SendAvatarDataToAllClients(false); | 1331 | SendAvatarDataToAllClients(false); |
1329 | }); | 1332 | }, null, "Scenepresence.ForceViewersUpdateName"); |
1330 | } | 1333 | } |
1331 | 1334 | ||
1332 | public int GetStateSource() | 1335 | public int GetStateSource() |
@@ -1809,14 +1812,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1809 | 1812 | ||
1810 | } | 1813 | } |
1811 | 1814 | ||
1812 | // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region | 1815 | // XXX: If we force an update after activity has completed, then multiple attachments do appear correctly on a destination region |
1813 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. | 1816 | // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. |
1814 | // This may be due to viewer code or it may be something we're not doing properly simulator side. | 1817 | // This may be due to viewer code or it may be something we're not doing properly simulator side. |
1815 | lock (m_attachments) | 1818 | WorkManager.RunJob( |
1816 | { | 1819 | "ScheduleAttachmentsForFullUpdate", |
1817 | foreach (SceneObjectGroup sog in m_attachments) | 1820 | o => ScheduleAttachmentsForFullUpdate(), |
1818 | sog.ScheduleGroupForFullUpdate(); | 1821 | null, |
1819 | } | 1822 | string.Format("Schedule attachments for full update for {0} in {1}", Name, Scene.Name), |
1823 | true); | ||
1820 | 1824 | ||
1821 | // m_log.DebugFormat( | 1825 | // m_log.DebugFormat( |
1822 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | 1826 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", |
@@ -1828,6 +1832,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1828 | } | 1832 | } |
1829 | } | 1833 | } |
1830 | 1834 | ||
1835 | private void ScheduleAttachmentsForFullUpdate() | ||
1836 | { | ||
1837 | lock (m_attachments) | ||
1838 | { | ||
1839 | foreach (SceneObjectGroup sog in m_attachments) | ||
1840 | sog.ScheduleGroupForFullUpdate(); | ||
1841 | } | ||
1842 | } | ||
1843 | |||
1831 | /// <summary> | 1844 | /// <summary> |
1832 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test | 1845 | /// Callback for the Camera view block check. Gets called with the results of the camera view block test |
1833 | /// hitYN is true when there's something in the way. | 1846 | /// hitYN is true when there's something in the way. |
@@ -3362,7 +3375,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3362 | SentInitialDataToClient = true; | 3375 | SentInitialDataToClient = true; |
3363 | 3376 | ||
3364 | // Send all scene object to the new client | 3377 | // Send all scene object to the new client |
3365 | Watchdog.RunInThread(delegate | 3378 | WorkManager.RunJob("SendInitialDataToClient", delegate |
3366 | { | 3379 | { |
3367 | // m_log.DebugFormat( | 3380 | // m_log.DebugFormat( |
3368 | // "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}", | 3381 | // "[SCENE PRESENCE]: Sending initial data to {0} agent {1} in {2}, tp flags {3}", |
@@ -3380,7 +3393,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3380 | if (e != null && e is SceneObjectGroup) | 3393 | if (e != null && e is SceneObjectGroup) |
3381 | ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); | 3394 | ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); |
3382 | } | 3395 | } |
3383 | }, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), null); | 3396 | }, null, string.Format("SendInitialDataToClient ({0} in {1})", Name, Scene.Name), false, true); |
3384 | } | 3397 | } |
3385 | 3398 | ||
3386 | /// <summary> | 3399 | /// <summary> |
@@ -3617,7 +3630,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3617 | agentpos.CopyFrom(cadu, ControllingClient.SessionId); | 3630 | agentpos.CopyFrom(cadu, ControllingClient.SessionId); |
3618 | 3631 | ||
3619 | // Let's get this out of the update loop | 3632 | // Let's get this out of the update loop |
3620 | Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); | 3633 | Util.FireAndForget( |
3634 | o => m_scene.SendOutChildAgentUpdates(agentpos, this), null, "ScenePresence.SendOutChildAgentUpdates"); | ||
3621 | } | 3635 | } |
3622 | } | 3636 | } |
3623 | 3637 | ||
@@ -4035,9 +4049,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
4035 | Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); | 4049 | Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); |
4036 | 4050 | ||
4037 | if (Scene.AttachmentsModule != null) | 4051 | if (Scene.AttachmentsModule != null) |
4038 | Scene.AttachmentsModule.CopyAttachments(cAgent, this); | 4052 | { |
4039 | 4053 | // If the JobEngine is running we can schedule this job now and continue rather than waiting for all | |
4040 | // This must occur after attachments are copied, as it releases the CompleteMovement() calling thread | 4054 | // attachments to copy, which might take a long time in the Hypergrid case as the entire inventory |
4055 | // graph is inspected for each attachments and assets possibly fetched. | ||
4056 | // | ||
4057 | // We don't need to worry about a race condition as the job to later start the scripts is also | ||
4058 | // JobEngine scheduled and so will always occur after this task. | ||
4059 | // XXX: This will not be true if JobEngine ever gets more than one thread. | ||
4060 | WorkManager.RunJob( | ||
4061 | "CopyAttachments", | ||
4062 | o => Scene.AttachmentsModule.CopyAttachments(cAgent, this), | ||
4063 | null, | ||
4064 | string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name), | ||
4065 | true); | ||
4066 | } | ||
4067 | |||
4068 | // This must occur after attachments are copied or scheduled to be copied, as it releases the CompleteMovement() calling thread | ||
4041 | // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart | 4069 | // originating from the client completing a teleport. Otherwise, CompleteMovement() code to restart |
4042 | // script attachments can outrace this thread. | 4070 | // script attachments can outrace this thread. |
4043 | lock (m_originRegionIDAccessLock) | 4071 | lock (m_originRegionIDAccessLock) |
@@ -4471,7 +4499,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4471 | } | 4499 | } |
4472 | } | 4500 | } |
4473 | } | 4501 | } |
4474 | }); | 4502 | }, null, "ScenePresence.SendScriptEventToAttachments"); |
4475 | } | 4503 | } |
4476 | 4504 | ||
4477 | /// <summary> | 4505 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 95f9caf..8f1e345 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | |||
@@ -224,7 +224,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
224 | public SimStatsReporter(Scene scene) | 224 | public SimStatsReporter(Scene scene) |
225 | { | 225 | { |
226 | m_scene = scene; | 226 | m_scene = scene; |
227 | m_reportedFpsCorrectionFactor = scene.MinFrameTime * m_nominalReportedFps; | 227 | m_reportedFpsCorrectionFactor = scene.MinFrameSeconds * m_nominalReportedFps; |
228 | m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); | 228 | m_statsUpdateFactor = (float)(m_statsUpdatesEveryMS / 1000); |
229 | ReportingRegion = scene.RegionInfo; | 229 | ReportingRegion = scene.RegionInfo; |
230 | 230 | ||
@@ -239,7 +239,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
239 | 239 | ||
240 | /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit | 240 | /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit |
241 | /// longer than ideal (which in itself is a concern). | 241 | /// longer than ideal (which in itself is a concern). |
242 | SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2); | 242 | SlowFramesStatReportThreshold = (int)Math.Ceiling(scene.MinFrameTicks * 1.2); |
243 | 243 | ||
244 | SlowFramesStat | 244 | SlowFramesStat |
245 | = new Stat( | 245 | = new Stat( |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs index 575a081..b6b3344 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs | |||
@@ -35,7 +35,6 @@ using OpenSim.Framework; | |||
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Tests.Common; | 37 | using OpenSim.Tests.Common; |
38 | using OpenSim.Tests.Common.Mock; | ||
39 | 38 | ||
40 | namespace OpenSim.Region.Framework.Scenes.Tests | 39 | namespace OpenSim.Region.Framework.Scenes.Tests |
41 | { | 40 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs index 2d831fa..6118004 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs | |||
@@ -36,7 +36,6 @@ using OpenSim.Framework.Communications; | |||
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
38 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | ||
40 | 39 | ||
41 | namespace OpenSim.Region.Framework.Scenes.Tests | 40 | namespace OpenSim.Region.Framework.Scenes.Tests |
42 | { | 41 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index a07d64c..bdf0700 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Framework.Communications; | |||
37 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
38 | using OpenSim.Services.Interfaces; | 38 | using OpenSim.Services.Interfaces; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 41 | namespace OpenSim.Region.Framework.Scenes.Tests |
43 | { | 42 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs index 969f73d..5635c20 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectCrossingTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | |||
37 | using OpenSim.Region.CoreModules.World.Land; | 37 | using OpenSim.Region.CoreModules.World.Land; |
38 | using OpenSim.Region.OptionalModules; | 38 | using OpenSim.Region.OptionalModules; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 41 | namespace OpenSim.Region.Framework.Scenes.Tests |
43 | { | 42 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index 5b5fb92..558ba2c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs | |||
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.World.Permissions; | |||
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.Framework.Scenes.Tests | 44 | namespace OpenSim.Region.Framework.Scenes.Tests |
46 | { | 45 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 0aefcbd..c2e0ae3 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs | |||
@@ -34,7 +34,6 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | using log4net; | 37 | using log4net; |
39 | 38 | ||
40 | namespace OpenSim.Region.Framework.Scenes.Tests | 39 | namespace OpenSim.Region.Framework.Scenes.Tests |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs index c264433..11e9084 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs | |||
@@ -33,7 +33,6 @@ using OpenSim.Framework; | |||
33 | using OpenSim.Framework.Communications; | 33 | using OpenSim.Framework.Communications; |
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Tests.Common; | 35 | using OpenSim.Tests.Common; |
36 | using OpenSim.Tests.Common.Mock; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | 37 | namespace OpenSim.Region.Framework.Scenes.Tests |
39 | { | 38 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs index a58e735..fdbe7ae 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs | |||
@@ -35,7 +35,6 @@ using OpenSim.Framework.Communications; | |||
35 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Tests.Common; | 37 | using OpenSim.Tests.Common; |
38 | using OpenSim.Tests.Common.Mock; | ||
39 | 38 | ||
40 | namespace OpenSim.Region.Framework.Scenes.Tests | 39 | namespace OpenSim.Region.Framework.Scenes.Tests |
41 | { | 40 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs index abaa1d1..974529a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs | |||
@@ -34,7 +34,6 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.Framework.Scenes.Tests | 38 | namespace OpenSim.Region.Framework.Scenes.Tests |
40 | { | 39 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs index 6985766..5ba754c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs | |||
@@ -34,7 +34,6 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.Framework.Scenes.Tests | 38 | namespace OpenSim.Region.Framework.Scenes.Tests |
40 | { | 39 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs index 4883ae7..cdebe25 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUndoRedoTests.cs | |||
@@ -33,7 +33,6 @@ using OpenSim.Framework; | |||
33 | using OpenSim.Framework.Communications; | 33 | using OpenSim.Framework.Communications; |
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Tests.Common; | 35 | using OpenSim.Tests.Common; |
36 | using OpenSim.Tests.Common.Mock; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | 37 | namespace OpenSim.Region.Framework.Scenes.Tests |
39 | { | 38 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs index 2b79271..fd49c88 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs | |||
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
39 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; | 40 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Region.Framework.Scenes.Tests | 43 | namespace OpenSim.Region.Framework.Scenes.Tests |
45 | { | 44 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index e2ed9c8..06e6423 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs | |||
@@ -44,7 +44,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer; | |||
44 | using OpenSim.Region.CoreModules.World.Serialiser; | 44 | using OpenSim.Region.CoreModules.World.Serialiser; |
45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
46 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 47 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
49 | 48 | ||
50 | namespace OpenSim.Region.Framework.Scenes.Tests | 49 | namespace OpenSim.Region.Framework.Scenes.Tests |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs index 1cd8ae9..42cfa1b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.World.Serialiser; | |||
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
44 | using OpenSim.Region.Physics.Manager; | 44 | using OpenSim.Region.Physics.Manager; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.Framework.Scenes.Tests | 47 | namespace OpenSim.Region.Framework.Scenes.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index d80afd3..c6e3b8b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Framework.Communications; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.Framework.Scenes.Tests | 41 | namespace OpenSim.Region.Framework.Scenes.Tests |
43 | { | 42 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs index 4fdfc74..cca30db 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs | |||
@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | |||
47 | using OpenSim.Region.Framework.Scenes; | 47 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Framework.Interfaces; | 48 | using OpenSim.Region.Framework.Interfaces; |
49 | using OpenSim.Tests.Common; | 49 | using OpenSim.Tests.Common; |
50 | using OpenSim.Tests.Common.Mock; | ||
51 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 50 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
52 | 51 | ||
53 | namespace OpenSim.Region.Framework.Scenes.Tests | 52 | namespace OpenSim.Region.Framework.Scenes.Tests |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index cf211a1..e14da8b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs | |||
@@ -40,7 +40,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer; | |||
40 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 40 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
41 | using OpenSim.Region.CoreModules.World.Permissions; | 41 | using OpenSim.Region.CoreModules.World.Permissions; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.Framework.Scenes.Tests | 44 | namespace OpenSim.Region.Framework.Scenes.Tests |
46 | { | 45 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index 2b84364..b775178 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Framework.Servers; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 38 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | using System.Threading; | 40 | using System.Threading; |
42 | 41 | ||
43 | namespace OpenSim.Region.Framework.Scenes.Tests | 42 | namespace OpenSim.Region.Framework.Scenes.Tests |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 8c25dbc..da93d44 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework.EntityTransfer; | |||
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
44 | using OpenSim.Region.CoreModules.World.Permissions; | 44 | using OpenSim.Region.CoreModules.World.Permissions; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.Framework.Scenes.Tests | 47 | namespace OpenSim.Region.Framework.Scenes.Tests |
49 | { | 48 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs index 1667002..2d36214 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs | |||
@@ -34,7 +34,6 @@ using OpenSim.Framework; | |||
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Region.Framework.Scenes.Tests | 38 | namespace OpenSim.Region.Framework.Scenes.Tests |
40 | { | 39 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs index 9a97acc..584a03c 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTelehubTests.cs | |||
@@ -32,7 +32,6 @@ using OpenSim.Region.Framework.Scenes; | |||
32 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
33 | using OpenSim.Services.Interfaces; | 33 | using OpenSim.Services.Interfaces; |
34 | using OpenSim.Tests.Common; | 34 | using OpenSim.Tests.Common; |
35 | using OpenSim.Tests.Common.Mock; | ||
36 | 35 | ||
37 | namespace OpenSim.Region.Framework.Scenes.Tests | 36 | namespace OpenSim.Region.Framework.Scenes.Tests |
38 | { | 37 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 52e4362..33ef83b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs | |||
@@ -42,7 +42,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
42 | using OpenSim.Region.CoreModules.World.Serialiser; | 42 | using OpenSim.Region.CoreModules.World.Serialiser; |
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
44 | using OpenSim.Tests.Common; | 44 | using OpenSim.Tests.Common; |
45 | using OpenSim.Tests.Common.Mock; | ||
46 | 45 | ||
47 | namespace OpenSim.Region.Framework.Scenes.Tests | 46 | namespace OpenSim.Region.Framework.Scenes.Tests |
48 | { | 47 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index f809267..9655d19 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.CoreModules.World.Serialiser; | |||
45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.Framework.Tests | 49 | namespace OpenSim.Region.Framework.Tests |
51 | { | 50 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 0736278..edc0a52 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.CoreModules.World.Serialiser; | |||
45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 45 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.Framework.Tests | 49 | namespace OpenSim.Region.Framework.Tests |
51 | { | 50 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index 1e59e3f..a12b170 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs | |||
@@ -33,7 +33,6 @@ using OpenSim.Framework; | |||
33 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
34 | using OpenSim.Services.Interfaces; | 34 | using OpenSim.Services.Interfaces; |
35 | using OpenSim.Tests.Common; | 35 | using OpenSim.Tests.Common; |
36 | using OpenSim.Tests.Common.Mock; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.Framework.Scenes.Tests | 37 | namespace OpenSim.Region.Framework.Scenes.Tests |
39 | { | 38 | { |
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index d07cc6a..2450cdb 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -57,22 +57,83 @@ namespace OpenSim.Region.Framework.Scenes | |||
57 | 57 | ||
58 | protected IAssetService m_assetService; | 58 | protected IAssetService m_assetService; |
59 | 59 | ||
60 | // /// <summary> | 60 | // /// <summary> |
61 | // /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate | 61 | // /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate |
62 | // /// asset was found by the asset service. | 62 | // /// asset was found by the asset service. |
63 | // /// </summary> | 63 | // /// </summary> |
64 | // private AssetBase m_requestedObjectAsset; | 64 | // private AssetBase m_requestedObjectAsset; |
65 | // | 65 | // |
66 | // /// <summary> | 66 | // /// <summary> |
67 | // /// Signal whether we are currently waiting for the asset service to deliver an asset. | 67 | // /// Signal whether we are currently waiting for the asset service to deliver an asset. |
68 | // /// </summary> | 68 | // /// </summary> |
69 | // private bool m_waitingForObjectAsset; | 69 | // private bool m_waitingForObjectAsset; |
70 | 70 | ||
71 | public UuidGatherer(IAssetService assetService) | 71 | public UuidGatherer(IAssetService assetService) |
72 | { | 72 | { |
73 | m_assetService = assetService; | 73 | m_assetService = assetService; |
74 | } | 74 | } |
75 | 75 | ||
76 | /// <summary> | ||
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | ||
78 | /// </summary> | ||
79 | /// <remarks> | ||
80 | /// This includes both those directly associated with | ||
81 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
82 | /// within this object). | ||
83 | /// This method assumes that the asset type associated with this asset in persistent storage is correct (which | ||
84 | /// should always be the case). So with this method we always need to retrieve asset data even if the asset | ||
85 | /// is of a type which is known not to reference any other assets | ||
86 | /// </remarks> | ||
87 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> | ||
88 | /// <param name="assetUuids">The assets gathered</param> | ||
89 | public void GatherAssetUuids(UUID assetUuid, IDictionary<UUID, sbyte> assetUuids) | ||
90 | { | ||
91 | // avoid infinite loops | ||
92 | if (assetUuids.ContainsKey(assetUuid)) | ||
93 | return; | ||
94 | |||
95 | try | ||
96 | { | ||
97 | AssetBase assetBase = GetAsset(assetUuid); | ||
98 | |||
99 | if (null != assetBase) | ||
100 | { | ||
101 | sbyte assetType = assetBase.Type; | ||
102 | assetUuids[assetUuid] = assetType; | ||
103 | |||
104 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) | ||
105 | { | ||
106 | GetWearableAssetUuids(assetBase, assetUuids); | ||
107 | } | ||
108 | else if ((sbyte)AssetType.Gesture == assetType) | ||
109 | { | ||
110 | GetGestureAssetUuids(assetBase, assetUuids); | ||
111 | } | ||
112 | else if ((sbyte)AssetType.Notecard == assetType) | ||
113 | { | ||
114 | GetTextEmbeddedAssetUuids(assetBase, assetUuids); | ||
115 | } | ||
116 | else if ((sbyte)AssetType.LSLText == assetType) | ||
117 | { | ||
118 | GetTextEmbeddedAssetUuids(assetBase, assetUuids); | ||
119 | } | ||
120 | else if ((sbyte)OpenSimAssetType.Material == assetType) | ||
121 | { | ||
122 | GetMaterialAssetUuids(assetBase, assetUuids); | ||
123 | } | ||
124 | else if ((sbyte)AssetType.Object == assetType) | ||
125 | { | ||
126 | GetSceneObjectAssetUuids(assetBase, assetUuids); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | catch (Exception) | ||
131 | { | ||
132 | m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid); | ||
133 | throw; | ||
134 | } | ||
135 | } | ||
136 | |||
76 | /// <summary> | 137 | /// <summary> |
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | 138 | /// Gather all the asset uuids associated with the asset referenced by a given uuid |
78 | /// </summary> | 139 | /// </summary> |
@@ -93,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
93 | try | 154 | try |
94 | { | 155 | { |
95 | assetUuids[assetUuid] = assetType; | 156 | assetUuids[assetUuid] = assetType; |
96 | 157 | ||
97 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) | 158 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) |
98 | { | 159 | { |
99 | GetWearableAssetUuids(assetUuid, assetUuids); | 160 | GetWearableAssetUuids(assetUuid, assetUuids); |
@@ -143,16 +204,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
143 | /// </param> | 204 | /// </param> |
144 | public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids) | 205 | public void GatherAssetUuids(SceneObjectGroup sceneObject, IDictionary<UUID, sbyte> assetUuids) |
145 | { | 206 | { |
146 | // m_log.DebugFormat( | 207 | // m_log.DebugFormat( |
147 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); | 208 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); |
148 | 209 | ||
149 | SceneObjectPart[] parts = sceneObject.Parts; | 210 | SceneObjectPart[] parts = sceneObject.Parts; |
150 | for (int i = 0; i < parts.Length; i++) | 211 | for (int i = 0; i < parts.Length; i++) |
151 | { | 212 | { |
152 | SceneObjectPart part = parts[i]; | 213 | SceneObjectPart part = parts[i]; |
153 | 214 | ||
154 | // m_log.DebugFormat( | 215 | // m_log.DebugFormat( |
155 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); | 216 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); |
156 | 217 | ||
157 | try | 218 | try |
158 | { | 219 | { |
@@ -173,7 +234,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
173 | } | 234 | } |
174 | } | 235 | } |
175 | } | 236 | } |
176 | 237 | ||
177 | // If the prim is a sculpt then preserve this information too | 238 | // If the prim is a sculpt then preserve this information too |
178 | if (part.Shape.SculptTexture != UUID.Zero) | 239 | if (part.Shape.SculptTexture != UUID.Zero) |
179 | assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; | 240 | assetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; |
@@ -201,13 +262,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
201 | } | 262 | } |
202 | 263 | ||
203 | TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); | 264 | TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); |
204 | 265 | ||
205 | // Now analyze this prim's inventory items to preserve all the uuids that they reference | 266 | // Now analyze this prim's inventory items to preserve all the uuids that they reference |
206 | foreach (TaskInventoryItem tii in taskDictionary.Values) | 267 | foreach (TaskInventoryItem tii in taskDictionary.Values) |
207 | { | 268 | { |
208 | // m_log.DebugFormat( | 269 | // m_log.DebugFormat( |
209 | // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", | 270 | // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", |
210 | // tii.Name, tii.Type, part.Name, part.UUID); | 271 | // tii.Name, tii.Type, part.Name, part.UUID); |
211 | 272 | ||
212 | if (!assetUuids.ContainsKey(tii.AssetID)) | 273 | if (!assetUuids.ContainsKey(tii.AssetID)) |
213 | GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids); | 274 | GatherAssetUuids(tii.AssetID, (sbyte)tii.Type, assetUuids); |
@@ -217,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
217 | // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and | 278 | // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and |
218 | // inventory transfer. There needs to be a way for a module to register a method without assuming a | 279 | // inventory transfer. There needs to be a way for a module to register a method without assuming a |
219 | // Scene.EventManager is present. | 280 | // Scene.EventManager is present. |
220 | // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); | 281 | // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); |
221 | 282 | ||
222 | 283 | ||
223 | // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs | 284 | // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs |
@@ -246,19 +307,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
246 | } | 307 | } |
247 | } | 308 | } |
248 | 309 | ||
249 | // /// <summary> | ||
250 | // /// The callback made when we request the asset for an object from the asset service. | ||
251 | // /// </summary> | ||
252 | // private void AssetReceived(string id, Object sender, AssetBase asset) | ||
253 | // { | ||
254 | // lock (this) | ||
255 | // { | ||
256 | // m_requestedObjectAsset = asset; | ||
257 | // m_waitingForObjectAsset = false; | ||
258 | // Monitor.Pulse(this); | ||
259 | // } | ||
260 | // } | ||
261 | |||
262 | /// <summary> | 310 | /// <summary> |
263 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps | 311 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps |
264 | /// stored in legacy format in part.DynAttrs | 312 | /// stored in legacy format in part.DynAttrs |
@@ -327,7 +375,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
327 | } | 375 | } |
328 | } | 376 | } |
329 | } | 377 | } |
330 | 378 | ||
331 | /// <summary> | 379 | /// <summary> |
332 | /// Get an asset synchronously, potentially using an asynchronous callback. If the | 380 | /// Get an asset synchronously, potentially using an asynchronous callback. If the |
333 | /// asynchronous callback is used, we will wait for it to complete. | 381 | /// asynchronous callback is used, we will wait for it to complete. |
@@ -340,54 +388,64 @@ namespace OpenSim.Region.Framework.Scenes | |||
340 | 388 | ||
341 | // XXX: Switching to do this synchronously where the call was async before but we always waited for it | 389 | // XXX: Switching to do this synchronously where the call was async before but we always waited for it |
342 | // to complete anyway! | 390 | // to complete anyway! |
343 | // m_waitingForObjectAsset = true; | 391 | // m_waitingForObjectAsset = true; |
344 | // m_assetCache.Get(uuid.ToString(), this, AssetReceived); | 392 | // m_assetCache.Get(uuid.ToString(), this, AssetReceived); |
345 | // | 393 | // |
346 | // // The asset cache callback can either | 394 | // // The asset cache callback can either |
347 | // // | 395 | // // |
348 | // // 1. Complete on the same thread (if the asset is already in the cache) or | 396 | // // 1. Complete on the same thread (if the asset is already in the cache) or |
349 | // // 2. Come in via a different thread (if we need to go fetch it). | 397 | // // 2. Come in via a different thread (if we need to go fetch it). |
350 | // // | 398 | // // |
351 | // // The code below handles both these alternatives. | 399 | // // The code below handles both these alternatives. |
352 | // lock (this) | 400 | // lock (this) |
353 | // { | 401 | // { |
354 | // if (m_waitingForObjectAsset) | 402 | // if (m_waitingForObjectAsset) |
355 | // { | 403 | // { |
356 | // Monitor.Wait(this); | 404 | // Monitor.Wait(this); |
357 | // m_waitingForObjectAsset = false; | 405 | // m_waitingForObjectAsset = false; |
358 | // } | 406 | // } |
359 | // } | 407 | // } |
360 | // | 408 | // |
361 | // return m_requestedObjectAsset; | 409 | // return m_requestedObjectAsset; |
362 | } | 410 | } |
363 | 411 | ||
364 | /// <summary> | 412 | /// <summary> |
365 | /// Record the asset uuids embedded within the given script. | 413 | /// Record the asset uuids embedded within the given text (e.g. a script). |
366 | /// </summary> | 414 | /// </summary> |
367 | /// <param name="scriptUuid"></param> | 415 | /// <param name="textAssetUuid"></param> |
368 | /// <param name="assetUuids">Dictionary in which to record the references</param> | 416 | /// <param name="assetUuids">Dictionary in which to record the references</param> |
369 | private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, sbyte> assetUuids) | 417 | private void GetTextEmbeddedAssetUuids(UUID textAssetUuid, IDictionary<UUID, sbyte> assetUuids) |
370 | { | 418 | { |
371 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); | 419 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); |
372 | 420 | ||
373 | AssetBase embeddingAsset = GetAsset(embeddingAssetId); | 421 | AssetBase textAsset = GetAsset(textAssetUuid); |
374 | 422 | ||
375 | if (null != embeddingAsset) | 423 | if (null != textAsset) |
376 | { | 424 | GetTextEmbeddedAssetUuids(textAsset, assetUuids); |
377 | string script = Utils.BytesToString(embeddingAsset.Data); | 425 | } |
378 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); | ||
379 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); | ||
380 | // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); | ||
381 | 426 | ||
382 | foreach (Match uuidMatch in uuidMatches) | 427 | /// <summary> |
383 | { | 428 | /// Record the asset uuids embedded within the given text (e.g. a script). |
384 | UUID uuid = new UUID(uuidMatch.Value); | 429 | /// </summary> |
385 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | 430 | /// <param name="textAsset"></param> |
431 | /// <param name="assetUuids">Dictionary in which to record the references</param> | ||
432 | private void GetTextEmbeddedAssetUuids(AssetBase textAsset, IDictionary<UUID, sbyte> assetUuids) | ||
433 | { | ||
434 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); | ||
386 | 435 | ||
387 | // Embedded asset references (if not false positives) could be for many types of asset, so we will | 436 | string script = Utils.BytesToString(textAsset.Data); |
388 | // label these as unknown. | 437 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); |
389 | assetUuids[uuid] = (sbyte)AssetType.Unknown; | 438 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); |
390 | } | 439 | // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); |
440 | |||
441 | foreach (Match uuidMatch in uuidMatches) | ||
442 | { | ||
443 | UUID uuid = new UUID(uuidMatch.Value); | ||
444 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | ||
445 | |||
446 | // Embedded asset references (if not false positives) could be for many types of asset, so we will | ||
447 | // label these as unknown. | ||
448 | assetUuids[uuid] = (sbyte)AssetType.Unknown; | ||
391 | } | 449 | } |
392 | } | 450 | } |
393 | 451 | ||
@@ -401,18 +459,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
401 | AssetBase assetBase = GetAsset(wearableAssetUuid); | 459 | AssetBase assetBase = GetAsset(wearableAssetUuid); |
402 | 460 | ||
403 | if (null != assetBase) | 461 | if (null != assetBase) |
462 | GetWearableAssetUuids(assetBase, assetUuids); | ||
463 | } | ||
464 | |||
465 | /// <summary> | ||
466 | /// Record the uuids referenced by the given wearable asset | ||
467 | /// </summary> | ||
468 | /// <param name="assetBase"></param> | ||
469 | /// <param name="assetUuids">Dictionary in which to record the references</param> | ||
470 | private void GetWearableAssetUuids(AssetBase assetBase, IDictionary<UUID, sbyte> assetUuids) | ||
471 | { | ||
472 | //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); | ||
473 | AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data); | ||
474 | wearableAsset.Decode(); | ||
475 | |||
476 | //m_log.DebugFormat( | ||
477 | // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); | ||
478 | |||
479 | foreach (UUID uuid in wearableAsset.Textures.Values) | ||
404 | { | 480 | { |
405 | //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); | 481 | assetUuids[uuid] = (sbyte)AssetType.Texture; |
406 | AssetWearable wearableAsset = new AssetBodypart(wearableAssetUuid, assetBase.Data); | ||
407 | wearableAsset.Decode(); | ||
408 | |||
409 | //m_log.DebugFormat( | ||
410 | // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); | ||
411 | |||
412 | foreach (UUID uuid in wearableAsset.Textures.Values) | ||
413 | { | ||
414 | assetUuids[uuid] = (sbyte)AssetType.Texture; | ||
415 | } | ||
416 | } | 482 | } |
417 | } | 483 | } |
418 | 484 | ||
@@ -425,25 +491,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
425 | /// <param name="assetUuids"></param> | 491 | /// <param name="assetUuids"></param> |
426 | private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) | 492 | private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) |
427 | { | 493 | { |
428 | AssetBase objectAsset = GetAsset(sceneObjectUuid); | 494 | AssetBase sceneObjectAsset = GetAsset(sceneObjectUuid); |
495 | |||
496 | if (null != sceneObjectAsset) | ||
497 | GetSceneObjectAssetUuids(sceneObjectAsset, assetUuids); | ||
498 | } | ||
499 | |||
500 | /// <summary> | ||
501 | /// Get all the asset uuids associated with a given object. This includes both those directly associated with | ||
502 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
503 | /// within this object). | ||
504 | /// </summary> | ||
505 | /// <param name="sceneObjectAsset"></param> | ||
506 | /// <param name="assetUuids"></param> | ||
507 | private void GetSceneObjectAssetUuids(AssetBase sceneObjectAsset, IDictionary<UUID, sbyte> assetUuids) | ||
508 | { | ||
509 | string xml = Utils.BytesToString(sceneObjectAsset.Data); | ||
429 | 510 | ||
430 | if (null != objectAsset) | 511 | CoalescedSceneObjects coa; |
512 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | ||
431 | { | 513 | { |
432 | string xml = Utils.BytesToString(objectAsset.Data); | 514 | foreach (SceneObjectGroup sog in coa.Objects) |
433 | 515 | GatherAssetUuids(sog, assetUuids); | |
434 | CoalescedSceneObjects coa; | 516 | } |
435 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | 517 | else |
436 | { | 518 | { |
437 | foreach (SceneObjectGroup sog in coa.Objects) | 519 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); |
438 | GatherAssetUuids(sog, assetUuids); | 520 | |
439 | } | 521 | if (null != sog) |
440 | else | 522 | GatherAssetUuids(sog, assetUuids); |
441 | { | ||
442 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | ||
443 | |||
444 | if (null != sog) | ||
445 | GatherAssetUuids(sog, assetUuids); | ||
446 | } | ||
447 | } | 523 | } |
448 | } | 524 | } |
449 | 525 | ||
@@ -454,12 +530,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | /// <param name="assetUuids"></param> | 530 | /// <param name="assetUuids"></param> |
455 | private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) | 531 | private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) |
456 | { | 532 | { |
457 | AssetBase assetBase = GetAsset(gestureUuid); | 533 | AssetBase gestureAsset = GetAsset(gestureUuid); |
458 | if (null == assetBase) | 534 | if (null == gestureAsset) |
459 | return; | 535 | return; |
460 | 536 | ||
461 | using (MemoryStream ms = new MemoryStream(assetBase.Data)) | 537 | GetGestureAssetUuids(gestureAsset, assetUuids); |
462 | using (StreamReader sr = new StreamReader(ms)) | 538 | } |
539 | |||
540 | /// <summary> | ||
541 | /// Get the asset uuid associated with a gesture | ||
542 | /// </summary> | ||
543 | /// <param name="gestureAsset"></param> | ||
544 | /// <param name="assetUuids"></param> | ||
545 | private void GetGestureAssetUuids(AssetBase gestureAsset, IDictionary<UUID, sbyte> assetUuids) | ||
546 | { | ||
547 | using (MemoryStream ms = new MemoryStream(gestureAsset.Data)) | ||
548 | using (StreamReader sr = new StreamReader(ms)) | ||
463 | { | 549 | { |
464 | sr.ReadLine(); // Unknown (Version?) | 550 | sr.ReadLine(); // Unknown (Version?) |
465 | sr.ReadLine(); // Unknown | 551 | sr.ReadLine(); // Unknown |
@@ -500,7 +586,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
500 | if (null == assetBase) | 586 | if (null == assetBase) |
501 | return; | 587 | return; |
502 | 588 | ||
503 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(assetBase.Data); | 589 | GetMaterialAssetUuids(assetBase, assetUuids); |
590 | } | ||
591 | |||
592 | /// <summary> | ||
593 | /// Get the asset uuid's referenced in a material. | ||
594 | /// </summary> | ||
595 | private void GetMaterialAssetUuids(AssetBase materialAsset, IDictionary<UUID, sbyte> assetUuids) | ||
596 | { | ||
597 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); | ||
504 | 598 | ||
505 | UUID normMap = mat["NormMap"].AsUUID(); | 599 | UUID normMap = mat["NormMap"].AsUUID(); |
506 | if (normMap != UUID.Zero) | 600 | if (normMap != UUID.Zero) |
@@ -536,7 +630,541 @@ namespace OpenSim.Region.Framework.Scenes | |||
536 | 630 | ||
537 | public AssetBase FetchAsset(UUID assetID) | 631 | public AssetBase FetchAsset(UUID assetID) |
538 | { | 632 | { |
633 | // Test if it's already here | ||
634 | AssetBase asset = m_assetService.Get(assetID.ToString()); | ||
635 | if (asset == null) | ||
636 | { | ||
637 | // It's not, so fetch it from abroad | ||
638 | asset = m_assetService.Get(m_assetServerURL + assetID.ToString()); | ||
639 | if (asset != null) | ||
640 | m_log.DebugFormat("[HGUUIDGatherer]: Copied asset {0} from {1} to local asset server", assetID, m_assetServerURL); | ||
641 | else | ||
642 | m_log.DebugFormat("[HGUUIDGatherer]: Failed to fetch asset {0} from {1}", assetID, m_assetServerURL); | ||
643 | } | ||
644 | //else | ||
645 | // m_log.DebugFormat("[HGUUIDGatherer]: Asset {0} from {1} was already here", assetID, m_assetServerURL); | ||
646 | |||
647 | return asset; | ||
648 | } | ||
649 | } | ||
650 | |||
651 | public class IteratingUuidGatherer | ||
652 | { | ||
653 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
654 | |||
655 | /// <summary> | ||
656 | /// Is gathering complete? | ||
657 | /// </summary> | ||
658 | public bool Complete { get { return m_assetUuidsToInspect.Count <= 0; } } | ||
659 | |||
660 | /// <summary> | ||
661 | /// Gets the next UUID to inspect. | ||
662 | /// </summary> | ||
663 | /// <value>If there is no next UUID then returns null</value> | ||
664 | public UUID? NextUuidToInspect | ||
665 | { | ||
666 | get | ||
667 | { | ||
668 | if (Complete) | ||
669 | return null; | ||
670 | else | ||
671 | return m_assetUuidsToInspect.Peek(); | ||
672 | } | ||
673 | } | ||
674 | |||
675 | protected IAssetService m_assetService; | ||
676 | |||
677 | protected IDictionary<UUID, sbyte> m_gatheredAssetUuids; | ||
678 | |||
679 | protected Queue<UUID> m_assetUuidsToInspect; | ||
680 | |||
681 | public IteratingUuidGatherer(IAssetService assetService) | ||
682 | { | ||
683 | m_assetService = assetService; | ||
684 | m_gatheredAssetUuids = new Dictionary<UUID, sbyte>(); | ||
685 | |||
686 | // FIXME: Not efficient for searching, can improve. | ||
687 | m_assetUuidsToInspect = new Queue<UUID>(); | ||
688 | } | ||
689 | |||
690 | public IDictionary<UUID, sbyte> GetGatheredUuids() | ||
691 | { | ||
692 | return new Dictionary<UUID, sbyte>(m_gatheredAssetUuids); | ||
693 | } | ||
694 | |||
695 | public bool AddAssetUuidToInspect(UUID uuid) | ||
696 | { | ||
697 | if (m_assetUuidsToInspect.Contains(uuid)) | ||
698 | return false; | ||
699 | |||
700 | m_assetUuidsToInspect.Enqueue(uuid); | ||
701 | |||
702 | return true; | ||
703 | } | ||
704 | |||
705 | /// <summary> | ||
706 | /// Gathers the next set of assets returned by the next uuid to get from the asset service. | ||
707 | /// </summary> | ||
708 | /// <returns>false if gathering is already complete, true otherwise</returns> | ||
709 | public bool GatherNext() | ||
710 | { | ||
711 | if (Complete) | ||
712 | return false; | ||
713 | |||
714 | GetAssetUuids(m_assetUuidsToInspect.Dequeue()); | ||
715 | |||
716 | return true; | ||
717 | } | ||
718 | |||
719 | /// <summary> | ||
720 | /// Gathers all remaining asset UUIDS no matter how many calls are required to the asset service. | ||
721 | /// </summary> | ||
722 | /// <returns>false if gathering is already complete, true otherwise</returns> | ||
723 | public bool GatherAll() | ||
724 | { | ||
725 | if (Complete) | ||
726 | return false; | ||
727 | |||
728 | while (GatherNext()); | ||
729 | |||
730 | return true; | ||
731 | } | ||
732 | |||
733 | /// <summary> | ||
734 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | ||
735 | /// </summary> | ||
736 | /// <remarks> | ||
737 | /// This includes both those directly associated with | ||
738 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
739 | /// within this object). | ||
740 | /// This method assumes that the asset type associated with this asset in persistent storage is correct (which | ||
741 | /// should always be the case). So with this method we always need to retrieve asset data even if the asset | ||
742 | /// is of a type which is known not to reference any other assets | ||
743 | /// </remarks> | ||
744 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> | ||
745 | private void GetAssetUuids(UUID assetUuid) | ||
746 | { | ||
747 | // avoid infinite loops | ||
748 | if (m_gatheredAssetUuids.ContainsKey(assetUuid)) | ||
749 | return; | ||
750 | |||
751 | try | ||
752 | { | ||
753 | AssetBase assetBase = GetAsset(assetUuid); | ||
754 | |||
755 | if (null != assetBase) | ||
756 | { | ||
757 | sbyte assetType = assetBase.Type; | ||
758 | m_gatheredAssetUuids[assetUuid] = assetType; | ||
759 | |||
760 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) | ||
761 | { | ||
762 | RecordWearableAssetUuids(assetBase); | ||
763 | } | ||
764 | else if ((sbyte)AssetType.Gesture == assetType) | ||
765 | { | ||
766 | RecordGestureAssetUuids(assetBase); | ||
767 | } | ||
768 | else if ((sbyte)AssetType.Notecard == assetType) | ||
769 | { | ||
770 | RecordTextEmbeddedAssetUuids(assetBase); | ||
771 | } | ||
772 | else if ((sbyte)AssetType.LSLText == assetType) | ||
773 | { | ||
774 | RecordTextEmbeddedAssetUuids(assetBase); | ||
775 | } | ||
776 | else if ((sbyte)OpenSimAssetType.Material == assetType) | ||
777 | { | ||
778 | RecordMaterialAssetUuids(assetBase); | ||
779 | } | ||
780 | else if ((sbyte)AssetType.Object == assetType) | ||
781 | { | ||
782 | RecordSceneObjectAssetUuids(assetBase); | ||
783 | } | ||
784 | } | ||
785 | } | ||
786 | catch (Exception) | ||
787 | { | ||
788 | m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid); | ||
789 | throw; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | private void RecordAssetUuids(UUID assetUuid, sbyte assetType) | ||
794 | { | ||
795 | // Here, we want to collect uuids which require further asset fetches but mark the others as gathered | ||
796 | try | ||
797 | { | ||
798 | m_gatheredAssetUuids[assetUuid] = assetType; | ||
799 | |||
800 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) | ||
801 | { | ||
802 | AddAssetUuidToInspect(assetUuid); | ||
803 | } | ||
804 | else if ((sbyte)AssetType.Gesture == assetType) | ||
805 | { | ||
806 | AddAssetUuidToInspect(assetUuid); | ||
807 | } | ||
808 | else if ((sbyte)AssetType.Notecard == assetType) | ||
809 | { | ||
810 | AddAssetUuidToInspect(assetUuid); | ||
811 | } | ||
812 | else if ((sbyte)AssetType.LSLText == assetType) | ||
813 | { | ||
814 | AddAssetUuidToInspect(assetUuid); | ||
815 | } | ||
816 | else if ((sbyte)OpenSimAssetType.Material == assetType) | ||
817 | { | ||
818 | AddAssetUuidToInspect(assetUuid); | ||
819 | } | ||
820 | else if ((sbyte)AssetType.Object == assetType) | ||
821 | { | ||
822 | AddAssetUuidToInspect(assetUuid); | ||
823 | } | ||
824 | } | ||
825 | catch (Exception) | ||
826 | { | ||
827 | m_log.ErrorFormat( | ||
828 | "[ITERATABLE UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}", | ||
829 | assetUuid, assetType); | ||
830 | throw; | ||
831 | } | ||
832 | } | ||
833 | |||
834 | /// <summary> | ||
835 | /// Gather all the asset uuids associated with a given object. | ||
836 | /// </summary> | ||
837 | /// <remarks> | ||
838 | /// This includes both those directly associated with | ||
839 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
840 | /// within this object). | ||
841 | /// </remarks> | ||
842 | /// <param name="sceneObject">The scene object for which to gather assets</param> | ||
843 | public void RecordAssetUuids(SceneObjectGroup sceneObject) | ||
844 | { | ||
845 | // m_log.DebugFormat( | ||
846 | // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); | ||
539 | 847 | ||
848 | SceneObjectPart[] parts = sceneObject.Parts; | ||
849 | for (int i = 0; i < parts.Length; i++) | ||
850 | { | ||
851 | SceneObjectPart part = parts[i]; | ||
852 | |||
853 | // m_log.DebugFormat( | ||
854 | // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); | ||
855 | |||
856 | try | ||
857 | { | ||
858 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | ||
859 | if (textureEntry != null) | ||
860 | { | ||
861 | // Get the prim's default texture. This will be used for faces which don't have their own texture | ||
862 | if (textureEntry.DefaultTexture != null) | ||
863 | RecordTextureEntryAssetUuids(textureEntry.DefaultTexture); | ||
864 | |||
865 | if (textureEntry.FaceTextures != null) | ||
866 | { | ||
867 | // Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture) | ||
868 | foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures) | ||
869 | { | ||
870 | if (texture != null) | ||
871 | RecordTextureEntryAssetUuids(texture); | ||
872 | } | ||
873 | } | ||
874 | } | ||
875 | |||
876 | // If the prim is a sculpt then preserve this information too | ||
877 | if (part.Shape.SculptTexture != UUID.Zero) | ||
878 | m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture; | ||
879 | |||
880 | if (part.Shape.ProjectionTextureUUID != UUID.Zero) | ||
881 | m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture; | ||
882 | |||
883 | if (part.CollisionSound != UUID.Zero) | ||
884 | m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound; | ||
885 | |||
886 | if (part.ParticleSystem.Length > 0) | ||
887 | { | ||
888 | try | ||
889 | { | ||
890 | Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0); | ||
891 | if (ps.Texture != UUID.Zero) | ||
892 | m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture; | ||
893 | } | ||
894 | catch (Exception) | ||
895 | { | ||
896 | m_log.WarnFormat( | ||
897 | "[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.", | ||
898 | part.Name, part.UUID, sceneObject.Name, sceneObject.UUID); | ||
899 | } | ||
900 | } | ||
901 | |||
902 | TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); | ||
903 | |||
904 | // Now analyze this prim's inventory items to preserve all the uuids that they reference | ||
905 | foreach (TaskInventoryItem tii in taskDictionary.Values) | ||
906 | { | ||
907 | // m_log.DebugFormat( | ||
908 | // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", | ||
909 | // tii.Name, tii.Type, part.Name, part.UUID); | ||
910 | |||
911 | if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID)) | ||
912 | RecordAssetUuids(tii.AssetID, (sbyte)tii.Type); | ||
913 | } | ||
914 | |||
915 | // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed | ||
916 | // to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and | ||
917 | // inventory transfer. There needs to be a way for a module to register a method without assuming a | ||
918 | // Scene.EventManager is present. | ||
919 | // part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids); | ||
920 | |||
921 | |||
922 | // still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs | ||
923 | RecordMaterialsUuids(part); | ||
924 | } | ||
925 | catch (Exception e) | ||
926 | { | ||
927 | m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); | ||
928 | m_log.DebugFormat( | ||
929 | "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)", | ||
930 | part.Shape.TextureEntry.Length); | ||
931 | } | ||
932 | } | ||
933 | } | ||
934 | |||
935 | /// <summary> | ||
936 | /// Collect all the asset uuids found in one face of a Texture Entry. | ||
937 | /// </summary> | ||
938 | private void RecordTextureEntryAssetUuids(Primitive.TextureEntryFace texture) | ||
939 | { | ||
940 | m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture; | ||
941 | |||
942 | if (texture.MaterialID != UUID.Zero) | ||
943 | AddAssetUuidToInspect(texture.MaterialID); | ||
944 | } | ||
945 | |||
946 | /// <summary> | ||
947 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps | ||
948 | /// stored in legacy format in part.DynAttrs | ||
949 | /// </summary> | ||
950 | /// <param name="part"></param> | ||
951 | public void RecordMaterialsUuids(SceneObjectPart part) | ||
952 | { | ||
953 | // scan thru the dynAttrs map of this part for any textures used as materials | ||
954 | OSD osdMaterials = null; | ||
955 | |||
956 | lock (part.DynAttrs) | ||
957 | { | ||
958 | if (part.DynAttrs.ContainsStore("OpenSim", "Materials")) | ||
959 | { | ||
960 | OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials"); | ||
961 | |||
962 | if (materialsStore == null) | ||
963 | return; | ||
964 | |||
965 | materialsStore.TryGetValue("Materials", out osdMaterials); | ||
966 | } | ||
967 | |||
968 | if (osdMaterials != null) | ||
969 | { | ||
970 | //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd)); | ||
971 | |||
972 | if (osdMaterials is OSDArray) | ||
973 | { | ||
974 | OSDArray matsArr = osdMaterials as OSDArray; | ||
975 | foreach (OSDMap matMap in matsArr) | ||
976 | { | ||
977 | try | ||
978 | { | ||
979 | if (matMap.ContainsKey("Material")) | ||
980 | { | ||
981 | OSDMap mat = matMap["Material"] as OSDMap; | ||
982 | if (mat.ContainsKey("NormMap")) | ||
983 | { | ||
984 | UUID normalMapId = mat["NormMap"].AsUUID(); | ||
985 | if (normalMapId != UUID.Zero) | ||
986 | { | ||
987 | m_gatheredAssetUuids[normalMapId] = (sbyte)AssetType.Texture; | ||
988 | //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString()); | ||
989 | } | ||
990 | } | ||
991 | if (mat.ContainsKey("SpecMap")) | ||
992 | { | ||
993 | UUID specularMapId = mat["SpecMap"].AsUUID(); | ||
994 | if (specularMapId != UUID.Zero) | ||
995 | { | ||
996 | m_gatheredAssetUuids[specularMapId] = (sbyte)AssetType.Texture; | ||
997 | //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString()); | ||
998 | } | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | } | ||
1003 | catch (Exception e) | ||
1004 | { | ||
1005 | m_log.Warn("[UUID Gatherer]: exception getting materials: " + e.Message); | ||
1006 | } | ||
1007 | } | ||
1008 | } | ||
1009 | } | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | /// <summary> | ||
1014 | /// Get an asset synchronously, potentially using an asynchronous callback. If the | ||
1015 | /// asynchronous callback is used, we will wait for it to complete. | ||
1016 | /// </summary> | ||
1017 | /// <param name="uuid"></param> | ||
1018 | /// <returns></returns> | ||
1019 | protected virtual AssetBase GetAsset(UUID uuid) | ||
1020 | { | ||
1021 | return m_assetService.Get(uuid.ToString()); | ||
1022 | } | ||
1023 | |||
1024 | /// <summary> | ||
1025 | /// Record the asset uuids embedded within the given text (e.g. a script). | ||
1026 | /// </summary> | ||
1027 | /// <param name="textAsset"></param> | ||
1028 | private void RecordTextEmbeddedAssetUuids(AssetBase textAsset) | ||
1029 | { | ||
1030 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); | ||
1031 | |||
1032 | string script = Utils.BytesToString(textAsset.Data); | ||
1033 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); | ||
1034 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); | ||
1035 | // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); | ||
1036 | |||
1037 | foreach (Match uuidMatch in uuidMatches) | ||
1038 | { | ||
1039 | UUID uuid = new UUID(uuidMatch.Value); | ||
1040 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | ||
1041 | |||
1042 | AddAssetUuidToInspect(uuid); | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | /// <summary> | ||
1047 | /// Record the uuids referenced by the given wearable asset | ||
1048 | /// </summary> | ||
1049 | /// <param name="assetBase"></param> | ||
1050 | private void RecordWearableAssetUuids(AssetBase assetBase) | ||
1051 | { | ||
1052 | //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); | ||
1053 | AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data); | ||
1054 | wearableAsset.Decode(); | ||
1055 | |||
1056 | //m_log.DebugFormat( | ||
1057 | // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); | ||
1058 | |||
1059 | foreach (UUID uuid in wearableAsset.Textures.Values) | ||
1060 | m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Texture; | ||
1061 | } | ||
1062 | |||
1063 | /// <summary> | ||
1064 | /// Get all the asset uuids associated with a given object. This includes both those directly associated with | ||
1065 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
1066 | /// within this object). | ||
1067 | /// </summary> | ||
1068 | /// <param name="sceneObjectAsset"></param> | ||
1069 | private void RecordSceneObjectAssetUuids(AssetBase sceneObjectAsset) | ||
1070 | { | ||
1071 | string xml = Utils.BytesToString(sceneObjectAsset.Data); | ||
1072 | |||
1073 | CoalescedSceneObjects coa; | ||
1074 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | ||
1075 | { | ||
1076 | foreach (SceneObjectGroup sog in coa.Objects) | ||
1077 | RecordAssetUuids(sog); | ||
1078 | } | ||
1079 | else | ||
1080 | { | ||
1081 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | ||
1082 | |||
1083 | if (null != sog) | ||
1084 | RecordAssetUuids(sog); | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | /// <summary> | ||
1089 | /// Get the asset uuid associated with a gesture | ||
1090 | /// </summary> | ||
1091 | /// <param name="gestureAsset"></param> | ||
1092 | private void RecordGestureAssetUuids(AssetBase gestureAsset) | ||
1093 | { | ||
1094 | using (MemoryStream ms = new MemoryStream(gestureAsset.Data)) | ||
1095 | using (StreamReader sr = new StreamReader(ms)) | ||
1096 | { | ||
1097 | sr.ReadLine(); // Unknown (Version?) | ||
1098 | sr.ReadLine(); // Unknown | ||
1099 | sr.ReadLine(); // Unknown | ||
1100 | sr.ReadLine(); // Name | ||
1101 | sr.ReadLine(); // Comment ? | ||
1102 | int count = Convert.ToInt32(sr.ReadLine()); // Item count | ||
1103 | |||
1104 | for (int i = 0 ; i < count ; i++) | ||
1105 | { | ||
1106 | string type = sr.ReadLine(); | ||
1107 | if (type == null) | ||
1108 | break; | ||
1109 | string name = sr.ReadLine(); | ||
1110 | if (name == null) | ||
1111 | break; | ||
1112 | string id = sr.ReadLine(); | ||
1113 | if (id == null) | ||
1114 | break; | ||
1115 | string unknown = sr.ReadLine(); | ||
1116 | if (unknown == null) | ||
1117 | break; | ||
1118 | |||
1119 | // If it can be parsed as a UUID, it is an asset ID | ||
1120 | UUID uuid; | ||
1121 | if (UUID.TryParse(id, out uuid)) | ||
1122 | m_gatheredAssetUuids[uuid] = (sbyte)AssetType.Animation; // the asset is either an Animation or a Sound, but this distinction isn't important | ||
1123 | } | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | /// <summary> | ||
1128 | /// Get the asset uuid's referenced in a material. | ||
1129 | /// </summary> | ||
1130 | private void RecordMaterialAssetUuids(AssetBase materialAsset) | ||
1131 | { | ||
1132 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); | ||
1133 | |||
1134 | UUID normMap = mat["NormMap"].AsUUID(); | ||
1135 | if (normMap != UUID.Zero) | ||
1136 | m_gatheredAssetUuids[normMap] = (sbyte)AssetType.Texture; | ||
1137 | |||
1138 | UUID specMap = mat["SpecMap"].AsUUID(); | ||
1139 | if (specMap != UUID.Zero) | ||
1140 | m_gatheredAssetUuids[specMap] = (sbyte)AssetType.Texture; | ||
1141 | } | ||
1142 | } | ||
1143 | |||
1144 | public class IteratingHGUuidGatherer : IteratingUuidGatherer | ||
1145 | { | ||
1146 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
1147 | |||
1148 | protected string m_assetServerURL; | ||
1149 | |||
1150 | public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL) | ||
1151 | : base(assetService) | ||
1152 | { | ||
1153 | m_assetServerURL = assetServerURL; | ||
1154 | if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("=")) | ||
1155 | m_assetServerURL = m_assetServerURL + "/"; | ||
1156 | } | ||
1157 | |||
1158 | protected override AssetBase GetAsset(UUID uuid) | ||
1159 | { | ||
1160 | if (string.Empty == m_assetServerURL) | ||
1161 | return base.GetAsset(uuid); | ||
1162 | else | ||
1163 | return FetchAsset(uuid); | ||
1164 | } | ||
1165 | |||
1166 | public AssetBase FetchAsset(UUID assetID) | ||
1167 | { | ||
540 | // Test if it's already here | 1168 | // Test if it's already here |
541 | AssetBase asset = m_assetService.Get(assetID.ToString()); | 1169 | AssetBase asset = m_assetService.Get(assetID.ToString()); |
542 | if (asset == null) | 1170 | if (asset == null) |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index e1aaf18..6fe86b2 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -71,7 +71,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
71 | m_client = client; | 71 | m_client = client; |
72 | m_scene = scene; | 72 | m_scene = scene; |
73 | 73 | ||
74 | Watchdog.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); | 74 | WorkManager.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true); |
75 | } | 75 | } |
76 | 76 | ||
77 | private void SendServerCommand(string command) | 77 | private void SendServerCommand(string command) |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs index 9d27386..a1682d2 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs | |||
@@ -58,7 +58,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
58 | 58 | ||
59 | m_listener.Start(50); | 59 | m_listener.Start(50); |
60 | 60 | ||
61 | Watchdog.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true); | 61 | WorkManager.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true); |
62 | m_baseScene = baseScene; | 62 | m_baseScene = baseScene; |
63 | } | 63 | } |
64 | 64 | ||
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 2ef3c4c..08d0fbf 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs | |||
@@ -487,9 +487,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
487 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); | 487 | report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding)); |
488 | 488 | ||
489 | report.AppendFormat( | 489 | report.AppendFormat( |
490 | "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}\n", | 490 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", |
491 | "Max", | 491 | "Max", |
492 | "Total", | 492 | "Target", |
493 | "Actual", | ||
493 | "Resend", | 494 | "Resend", |
494 | "Land", | 495 | "Land", |
495 | "Wind", | 496 | "Wind", |
@@ -500,7 +501,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
500 | 501 | ||
501 | report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); | 502 | report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", ""); |
502 | report.AppendFormat( | 503 | report.AppendFormat( |
503 | "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}\n", | 504 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", |
505 | "kb/s", | ||
504 | "kb/s", | 506 | "kb/s", |
505 | "kb/s", | 507 | "kb/s", |
506 | "kb/s", | 508 | "kb/s", |
@@ -513,8 +515,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
513 | 515 | ||
514 | report.AppendLine(); | 516 | report.AppendLine(); |
515 | 517 | ||
516 | bool firstClient = true; | ||
517 | |||
518 | lock (m_scenes) | 518 | lock (m_scenes) |
519 | { | 519 | { |
520 | foreach (Scene scene in m_scenes.Values) | 520 | foreach (Scene scene in m_scenes.Values) |
@@ -526,12 +526,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
526 | { | 526 | { |
527 | LLClientView llClient = client as LLClientView; | 527 | LLClientView llClient = client as LLClientView; |
528 | 528 | ||
529 | if (firstClient) | ||
530 | { | ||
531 | report.AppendLine(GetServerThrottlesReport(llClient.UDPServer)); | ||
532 | firstClient = false; | ||
533 | } | ||
534 | |||
535 | bool isChild = client.SceneAgent.IsChildAgent; | 529 | bool isChild = client.SceneAgent.IsChildAgent; |
536 | if (isChild && !showChildren) | 530 | if (isChild && !showChildren) |
537 | return; | 531 | return; |
@@ -550,8 +544,11 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
550 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); | 544 | report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding)); |
551 | 545 | ||
552 | report.AppendFormat( | 546 | report.AppendFormat( |
553 | "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}", | 547 | "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n", |
554 | (ci.maxThrottle * 8) / 1000, | 548 | ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-", |
549 | llUdpClient.FlowThrottle.AdaptiveEnabled | ||
550 | ? ((ci.targetThrottle * 8) / 1000).ToString() | ||
551 | : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(), | ||
555 | (ci.totalThrottle * 8) / 1000, | 552 | (ci.totalThrottle * 8) / 1000, |
556 | (ci.resendThrottle * 8) / 1000, | 553 | (ci.resendThrottle * 8) / 1000, |
557 | (ci.landThrottle * 8) / 1000, | 554 | (ci.landThrottle * 8) / 1000, |
@@ -559,9 +556,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
559 | (ci.cloudThrottle * 8) / 1000, | 556 | (ci.cloudThrottle * 8) / 1000, |
560 | (ci.taskThrottle * 8) / 1000, | 557 | (ci.taskThrottle * 8) / 1000, |
561 | (ci.textureThrottle * 8) / 1000, | 558 | (ci.textureThrottle * 8) / 1000, |
562 | (ci.assetThrottle * 8) / 1000); | 559 | (ci.assetThrottle * 8) / 1000); |
563 | |||
564 | report.AppendLine(); | ||
565 | } | 560 | } |
566 | }); | 561 | }); |
567 | } | 562 | } |
@@ -569,37 +564,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
569 | 564 | ||
570 | return report.ToString(); | 565 | return report.ToString(); |
571 | } | 566 | } |
572 | |||
573 | protected string GetServerThrottlesReport(LLUDPServer udpServer) | ||
574 | { | ||
575 | StringBuilder report = new StringBuilder(); | ||
576 | |||
577 | int columnPadding = 2; | ||
578 | int maxNameLength = 18; | ||
579 | int maxRegionNameLength = 14; | ||
580 | int maxTypeLength = 4; | ||
581 | |||
582 | string name = "SERVER AGENT RATES"; | ||
583 | |||
584 | report.Append(GetColumnEntry(name, maxNameLength, columnPadding)); | ||
585 | report.Append(GetColumnEntry("-", maxRegionNameLength, columnPadding)); | ||
586 | report.Append(GetColumnEntry("-", maxTypeLength, columnPadding)); | ||
587 | |||
588 | ThrottleRates throttleRates = udpServer.ThrottleRates; | ||
589 | report.AppendFormat( | ||
590 | "{0,8} {1,7} {2,8} {3,7} {4,7} {5,7} {6,7} {7,9} {8,7}", | ||
591 | "-", | ||
592 | (throttleRates.Total * 8) / 1000, | ||
593 | (throttleRates.Resend * 8) / 1000, | ||
594 | (throttleRates.Land * 8) / 1000, | ||
595 | (throttleRates.Wind * 8) / 1000, | ||
596 | (throttleRates.Cloud * 8) / 1000, | ||
597 | (throttleRates.Task * 8) / 1000, | ||
598 | (throttleRates.Texture * 8) / 1000, | ||
599 | (throttleRates.Asset * 8) / 1000); | ||
600 | |||
601 | return report.ToString(); | ||
602 | } | ||
603 | 567 | ||
604 | /// <summary> | 568 | /// <summary> |
605 | /// Show client stats data | 569 | /// Show client stats data |
@@ -641,7 +605,9 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden | |||
641 | string.Format( | 605 | string.Format( |
642 | "{0} ({1:0.00}%)", | 606 | "{0} ({1:0.00}%)", |
643 | llClient.TotalAgentUpdates, | 607 | llClient.TotalAgentUpdates, |
644 | (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100)); | 608 | cinfo.SyncRequests.ContainsKey("AgentUpdate") |
609 | ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100 | ||
610 | : 0)); | ||
645 | } | 611 | } |
646 | }); | 612 | }); |
647 | } | 613 | } |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index fa35f0f..f67f613 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | |||
@@ -51,7 +51,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
51 | { | 51 | { |
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | 53 | ||
54 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | 54 | private List<Scene> m_scenes = new List<Scene>(); |
55 | |||
55 | // private IAvatarFactoryModule m_avatarFactory; | 56 | // private IAvatarFactoryModule m_avatarFactory; |
56 | 57 | ||
57 | public string Name { get { return "Appearance Information Module"; } } | 58 | public string Name { get { return "Appearance Information Module"; } } |
@@ -83,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
83 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | 84 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); |
84 | 85 | ||
85 | lock (m_scenes) | 86 | lock (m_scenes) |
86 | m_scenes.Remove(scene.RegionInfo.RegionID); | 87 | m_scenes.Remove(scene); |
87 | } | 88 | } |
88 | 89 | ||
89 | public void RegionLoaded(Scene scene) | 90 | public void RegionLoaded(Scene scene) |
@@ -91,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
91 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | 92 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); |
92 | 93 | ||
93 | lock (m_scenes) | 94 | lock (m_scenes) |
94 | m_scenes[scene.RegionInfo.RegionID] = scene; | 95 | m_scenes.Add(scene); |
95 | 96 | ||
96 | scene.AddCommand( | 97 | scene.AddCommand( |
97 | "Users", this, "show appearance", | 98 | "Users", this, "show appearance", |
@@ -102,7 +103,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
102 | scene.AddCommand( | 103 | scene.AddCommand( |
103 | "Users", this, "appearance show", | 104 | "Users", this, "appearance show", |
104 | "appearance show [<first-name> <last-name>]", | 105 | "appearance show [<first-name> <last-name>]", |
105 | "Show appearance information for each avatar in the simulator.", | 106 | "Show appearance information for avatars.", |
106 | "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " | 107 | "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " |
107 | + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." | 108 | + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud." |
108 | + "\nOptionally, you can view just a particular avatar's appearance information." | 109 | + "\nOptionally, you can view just a particular avatar's appearance information." |
@@ -132,6 +133,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
132 | "Find out which avatar uses the given asset as a baked texture, if any.", | 133 | "Find out which avatar uses the given asset as a baked texture, if any.", |
133 | "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", | 134 | "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", |
134 | HandleFindAppearanceCommand); | 135 | HandleFindAppearanceCommand); |
136 | |||
137 | scene.AddCommand( | ||
138 | "Users", this, "wearables show", | ||
139 | "wearables show [<first-name> <last-name>]", | ||
140 | "Show information about wearables for avatars.", | ||
141 | "If no avatar name is given then a general summary for all avatars in the scene is shown.\n" | ||
142 | + "If an avatar name is given then specific information about current wearables is shown.", | ||
143 | HandleShowWearablesCommand); | ||
144 | |||
145 | scene.AddCommand( | ||
146 | "Users", this, "wearables check", | ||
147 | "wearables check <first-name> <last-name>", | ||
148 | "Check that the wearables of a given avatar in the scene are valid.", | ||
149 | "This currently checks that the wearable assets themselves and any assets referenced by them exist.", | ||
150 | HandleCheckWearablesCommand); | ||
135 | } | 151 | } |
136 | 152 | ||
137 | private void HandleSendAppearanceCommand(string module, string[] cmd) | 153 | private void HandleSendAppearanceCommand(string module, string[] cmd) |
@@ -155,7 +171,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
155 | 171 | ||
156 | lock (m_scenes) | 172 | lock (m_scenes) |
157 | { | 173 | { |
158 | foreach (Scene scene in m_scenes.Values) | 174 | foreach (Scene scene in m_scenes) |
159 | { | 175 | { |
160 | if (targetNameSupplied) | 176 | if (targetNameSupplied) |
161 | { | 177 | { |
@@ -186,7 +202,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
186 | } | 202 | } |
187 | } | 203 | } |
188 | 204 | ||
189 | protected void HandleShowAppearanceCommand(string module, string[] cmd) | 205 | private void HandleShowAppearanceCommand(string module, string[] cmd) |
190 | { | 206 | { |
191 | if (cmd.Length != 2 && cmd.Length < 4) | 207 | if (cmd.Length != 2 && cmd.Length < 4) |
192 | { | 208 | { |
@@ -207,7 +223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
207 | 223 | ||
208 | lock (m_scenes) | 224 | lock (m_scenes) |
209 | { | 225 | { |
210 | foreach (Scene scene in m_scenes.Values) | 226 | foreach (Scene scene in m_scenes) |
211 | { | 227 | { |
212 | if (targetNameSupplied) | 228 | if (targetNameSupplied) |
213 | { | 229 | { |
@@ -243,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
243 | 259 | ||
244 | lock (m_scenes) | 260 | lock (m_scenes) |
245 | { | 261 | { |
246 | foreach (Scene scene in m_scenes.Values) | 262 | foreach (Scene scene in m_scenes) |
247 | { | 263 | { |
248 | ScenePresence sp = scene.GetScenePresence(firstname, lastname); | 264 | ScenePresence sp = scene.GetScenePresence(firstname, lastname); |
249 | if (sp != null && !sp.IsChildAgent) | 265 | if (sp != null && !sp.IsChildAgent) |
@@ -263,7 +279,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
263 | } | 279 | } |
264 | } | 280 | } |
265 | 281 | ||
266 | protected void HandleFindAppearanceCommand(string module, string[] cmd) | 282 | private void HandleFindAppearanceCommand(string module, string[] cmd) |
267 | { | 283 | { |
268 | if (cmd.Length != 3) | 284 | if (cmd.Length != 3) |
269 | { | 285 | { |
@@ -277,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
277 | 293 | ||
278 | lock (m_scenes) | 294 | lock (m_scenes) |
279 | { | 295 | { |
280 | foreach (Scene scene in m_scenes.Values) | 296 | foreach (Scene scene in m_scenes) |
281 | { | 297 | { |
282 | scene.ForEachRootScenePresence( | 298 | scene.ForEachRootScenePresence( |
283 | sp => | 299 | sp => |
@@ -304,5 +320,161 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
304 | string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray())); | 320 | string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray())); |
305 | } | 321 | } |
306 | } | 322 | } |
323 | |||
324 | protected void HandleShowWearablesCommand(string module, string[] cmd) | ||
325 | { | ||
326 | if (cmd.Length != 2 && cmd.Length < 4) | ||
327 | { | ||
328 | MainConsole.Instance.OutputFormat("Usage: wearables show [<first-name> <last-name>]"); | ||
329 | return; | ||
330 | } | ||
331 | |||
332 | bool targetNameSupplied = false; | ||
333 | string optionalTargetFirstName = null; | ||
334 | string optionalTargetLastName = null; | ||
335 | |||
336 | if (cmd.Length >= 4) | ||
337 | { | ||
338 | targetNameSupplied = true; | ||
339 | optionalTargetFirstName = cmd[2]; | ||
340 | optionalTargetLastName = cmd[3]; | ||
341 | } | ||
342 | |||
343 | StringBuilder sb = new StringBuilder(); | ||
344 | |||
345 | if (targetNameSupplied) | ||
346 | { | ||
347 | lock (m_scenes) | ||
348 | { | ||
349 | foreach (Scene scene in m_scenes) | ||
350 | { | ||
351 | ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); | ||
352 | if (sp != null && !sp.IsChildAgent) | ||
353 | AppendWearablesDetailReport(sp, sb); | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
360 | cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize); | ||
361 | cdt.AddColumn("Wearables", 2); | ||
362 | |||
363 | lock (m_scenes) | ||
364 | { | ||
365 | foreach (Scene scene in m_scenes) | ||
366 | { | ||
367 | scene.ForEachRootScenePresence( | ||
368 | sp => | ||
369 | { | ||
370 | int count = 0; | ||
371 | |||
372 | for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) | ||
373 | count += sp.Appearance.Wearables[i].Count; | ||
374 | |||
375 | cdt.AddRow(sp.Name, count); | ||
376 | } | ||
377 | ); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | sb.Append(cdt.ToString()); | ||
382 | } | ||
383 | |||
384 | MainConsole.Instance.Output(sb.ToString()); | ||
385 | } | ||
386 | |||
387 | private void HandleCheckWearablesCommand(string module, string[] cmd) | ||
388 | { | ||
389 | if (cmd.Length != 4) | ||
390 | { | ||
391 | MainConsole.Instance.OutputFormat("Usage: wearables check <first-name> <last-name>"); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | string firstname = cmd[2]; | ||
396 | string lastname = cmd[3]; | ||
397 | |||
398 | StringBuilder sb = new StringBuilder(); | ||
399 | UuidGatherer uuidGatherer = new UuidGatherer(m_scenes[0].AssetService); | ||
400 | |||
401 | lock (m_scenes) | ||
402 | { | ||
403 | foreach (Scene scene in m_scenes) | ||
404 | { | ||
405 | ScenePresence sp = scene.GetScenePresence(firstname, lastname); | ||
406 | if (sp != null && !sp.IsChildAgent) | ||
407 | { | ||
408 | sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name); | ||
409 | |||
410 | for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) | ||
411 | { | ||
412 | AvatarWearable aw = sp.Appearance.Wearables[i]; | ||
413 | |||
414 | if (aw.Count > 0) | ||
415 | { | ||
416 | sb.Append(Enum.GetName(typeof(WearableType), i)); | ||
417 | sb.Append("\n"); | ||
418 | |||
419 | for (int j = 0; j < aw.Count; j++) | ||
420 | { | ||
421 | WearableItem wi = aw[j]; | ||
422 | |||
423 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
424 | cdl.Indent = 2; | ||
425 | cdl.AddRow("Item UUID", wi.ItemID); | ||
426 | cdl.AddRow("Assets", ""); | ||
427 | sb.Append(cdl.ToString()); | ||
428 | |||
429 | Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); | ||
430 | uuidGatherer.GatherAssetUuids(wi.AssetID, assetUuids); | ||
431 | string[] assetStrings | ||
432 | = Array.ConvertAll<UUID, string>(assetUuids.Keys.ToArray(), u => u.ToString()); | ||
433 | |||
434 | bool[] existChecks = scene.AssetService.AssetsExist(assetStrings); | ||
435 | |||
436 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
437 | cdt.Indent = 4; | ||
438 | cdt.AddColumn("Type", 10); | ||
439 | cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize); | ||
440 | cdt.AddColumn("Found", 5); | ||
441 | |||
442 | for (int k = 0; k < existChecks.Length; k++) | ||
443 | cdt.AddRow((AssetType)assetUuids[new UUID(assetStrings[k])], assetStrings[k], existChecks[k] ? "yes" : "no"); | ||
444 | |||
445 | sb.Append(cdt.ToString()); | ||
446 | sb.Append("\n"); | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | |||
454 | MainConsole.Instance.Output(sb.ToString()); | ||
455 | } | ||
456 | |||
457 | private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb) | ||
458 | { | ||
459 | sb.AppendFormat("\nWearables for {0}\n", sp.Name); | ||
460 | |||
461 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
462 | cdt.AddColumn("Type", 10); | ||
463 | cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize); | ||
464 | cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize); | ||
465 | |||
466 | for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) | ||
467 | { | ||
468 | AvatarWearable aw = sp.Appearance.Wearables[i]; | ||
469 | |||
470 | for (int j = 0; j < aw.Count; j++) | ||
471 | { | ||
472 | WearableItem wi = aw[j]; | ||
473 | cdt.AddRow(Enum.GetName(typeof(WearableType), i), wi.ItemID, wi.AssetID); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | sb.Append(cdt.ToString()); | ||
478 | } | ||
307 | } | 479 | } |
308 | } \ No newline at end of file | 480 | } \ No newline at end of file |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs index bdd07e0..6985371 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs | |||
@@ -359,7 +359,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat | |||
359 | 359 | ||
360 | m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); | 360 | m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); |
361 | 361 | ||
362 | Watchdog.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); | 362 | WorkManager.StartThread(ListenerRun, "IRCConnectionListenerThread", ThreadPriority.Normal, true, false); |
363 | 363 | ||
364 | // This is the message order recommended by RFC 2812 | 364 | // This is the message order recommended by RFC 2812 |
365 | if (m_password != null) | 365 | if (m_password != null) |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index d944087..e03e71d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | |||
@@ -46,7 +46,6 @@ using OpenSim.Region.CoreModules.Framework; | |||
46 | using OpenSim.Region.Framework.Scenes; | 46 | using OpenSim.Region.Framework.Scenes; |
47 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; | 47 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; |
48 | using OpenSim.Tests.Common; | 48 | using OpenSim.Tests.Common; |
49 | using OpenSim.Tests.Common.Mock; | ||
50 | 49 | ||
51 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests | 50 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests |
52 | { | 51 | { |
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index a6c12fd..b69676b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs | |||
@@ -323,7 +323,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
323 | public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param) | 323 | public UUID JsonRezAtRoot(UUID hostID, UUID scriptID, string item, Vector3 pos, Vector3 vel, Quaternion rot, string param) |
324 | { | 324 | { |
325 | UUID reqID = UUID.Random(); | 325 | UUID reqID = UUID.Random(); |
326 | Util.FireAndForget(o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param)); | 326 | Util.FireAndForget( |
327 | o => DoJsonRezObject(hostID, scriptID, reqID, item, pos, vel, rot, param), null, "JsonStoreScriptModule.DoJsonRezObject"); | ||
327 | return reqID; | 328 | return reqID; |
328 | } | 329 | } |
329 | 330 | ||
@@ -336,7 +337,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
336 | public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) | 337 | public UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string notecardIdentifier) |
337 | { | 338 | { |
338 | UUID reqID = UUID.Random(); | 339 | UUID reqID = UUID.Random(); |
339 | Util.FireAndForget(o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier)); | 340 | Util.FireAndForget( |
341 | o => DoJsonReadNotecard(reqID, hostID, scriptID, storeID, path, notecardIdentifier), null, "JsonStoreScriptModule.JsonReadNotecard"); | ||
340 | return reqID; | 342 | return reqID; |
341 | } | 343 | } |
342 | 344 | ||
@@ -349,7 +351,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
349 | public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) | 351 | public UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name) |
350 | { | 352 | { |
351 | UUID reqID = UUID.Random(); | 353 | UUID reqID = UUID.Random(); |
352 | Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); }); | 354 | Util.FireAndForget( |
355 | o => DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name), null, "JsonStoreScriptModule.DoJsonWriteNotecard"); | ||
353 | return reqID; | 356 | return reqID; |
354 | } | 357 | } |
355 | 358 | ||
@@ -464,7 +467,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
464 | public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) | 467 | public UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path) |
465 | { | 468 | { |
466 | UUID reqID = UUID.Random(); | 469 | UUID reqID = UUID.Random(); |
467 | Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); }); | 470 | Util.FireAndForget( |
471 | o => DoJsonTakeValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonTakeValue"); | ||
468 | return reqID; | 472 | return reqID; |
469 | } | 473 | } |
470 | 474 | ||
@@ -472,7 +476,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
472 | public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | 476 | public UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) |
473 | { | 477 | { |
474 | UUID reqID = UUID.Random(); | 478 | UUID reqID = UUID.Random(); |
475 | Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); }); | 479 | Util.FireAndForget( |
480 | o => DoJsonTakeValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonTakeValueJson"); | ||
476 | return reqID; | 481 | return reqID; |
477 | } | 482 | } |
478 | 483 | ||
@@ -485,7 +490,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
485 | public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) | 490 | public UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path) |
486 | { | 491 | { |
487 | UUID reqID = UUID.Random(); | 492 | UUID reqID = UUID.Random(); |
488 | Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); }); | 493 | Util.FireAndForget( |
494 | o => DoJsonReadValue(scriptID,reqID,storeID,path,false), null, "JsonStoreScriptModule.DoJsonReadValue"); | ||
489 | return reqID; | 495 | return reqID; |
490 | } | 496 | } |
491 | 497 | ||
@@ -493,7 +499,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore | |||
493 | public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) | 499 | public UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path) |
494 | { | 500 | { |
495 | UUID reqID = UUID.Random(); | 501 | UUID reqID = UUID.Random(); |
496 | Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); }); | 502 | Util.FireAndForget( |
503 | o => DoJsonReadValue(scriptID,reqID,storeID,path,true), null, "JsonStoreScriptModule.DoJsonReadValueJson"); | ||
497 | return reqID; | 504 | return reqID; |
498 | } | 505 | } |
499 | 506 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs index 21e2758..99a7076 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/Tests/JsonStoreScriptModuleTests.cs | |||
@@ -40,7 +40,6 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
40 | using OpenSim.Region.ScriptEngine.Shared.Api; | 40 | using OpenSim.Region.ScriptEngine.Shared.Api; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests | 44 | namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests |
46 | { | 45 | { |
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs index 6e0a80a..d37369c 100644 --- a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs +++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs | |||
@@ -294,7 +294,8 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport | |||
294 | for (int i = 0 ; i < selection.Count ; i++) | 294 | for (int i = 0 ; i < selection.Count ; i++) |
295 | sel.Add(selection[i].AsUInteger()); | 295 | sel.Add(selection[i].AsUInteger()); |
296 | 296 | ||
297 | Util.FireAndForget(x => { m_module.HandleMenuSelection(action, m_agentID, sel); }); | 297 | Util.FireAndForget( |
298 | x => { m_module.HandleMenuSelection(action, m_agentID, sel); }, null, "DynamicMenuModule.HandleMenuSelection"); | ||
298 | 299 | ||
299 | Encoding encoding = Encoding.UTF8; | 300 | Encoding encoding = Encoding.UTF8; |
300 | return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); | 301 | return encoding.GetBytes(OSDParser.SerializeLLSDXmlString(new OSD())); |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index e82351e..0bebb58 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Services.AvatarService; | 44 | using OpenSim.Services.AvatarService; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.OptionalModules.World.NPC.Tests | 47 | namespace OpenSim.Region.OptionalModules.World.NPC.Tests |
49 | { | 48 | { |
@@ -300,7 +299,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
300 | public void TestMove() | 299 | public void TestMove() |
301 | { | 300 | { |
302 | TestHelpers.InMethod(); | 301 | TestHelpers.InMethod(); |
303 | // log4net.Config.XmlConfigurator.Configure(); | 302 | // TestHelpers.EnableLogging(); |
304 | 303 | ||
305 | SetUpScene(); | 304 | SetUpScene(); |
306 | 305 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index a303972..4c54f9f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -174,15 +174,19 @@ public sealed class BSCharacter : BSPhysObject | |||
174 | PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); | 174 | PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); |
175 | 175 | ||
176 | // Do this after the object has been added to the world | 176 | // Do this after the object has been added to the world |
177 | PhysBody.collisionType = CollisionType.Avatar; | 177 | if (BSParam.AvatarToAvatarCollisionsByDefault) |
178 | PhysBody.collisionType = CollisionType.Avatar; | ||
179 | else | ||
180 | PhysBody.collisionType = CollisionType.PhantomToOthersAvatar; | ||
181 | |||
178 | PhysBody.ApplyCollisionMask(PhysScene); | 182 | PhysBody.ApplyCollisionMask(PhysScene); |
179 | } | 183 | } |
180 | 184 | ||
181 | |||
182 | public override void RequestPhysicsterseUpdate() | 185 | public override void RequestPhysicsterseUpdate() |
183 | { | 186 | { |
184 | base.RequestPhysicsterseUpdate(); | 187 | base.RequestPhysicsterseUpdate(); |
185 | } | 188 | } |
189 | |||
186 | // No one calls this method so I don't know what it could possibly mean | 190 | // No one calls this method so I don't know what it could possibly mean |
187 | public override bool Stopped { get { return false; } } | 191 | public override bool Stopped { get { return false; } } |
188 | 192 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 867d6ff..e7f4def 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -132,6 +132,7 @@ public static class BSParam | |||
132 | public static float PhysicsUnmanLoggingFrames { get; private set; } | 132 | public static float PhysicsUnmanLoggingFrames { get; private set; } |
133 | 133 | ||
134 | // Avatar parameters | 134 | // Avatar parameters |
135 | public static bool AvatarToAvatarCollisionsByDefault { get; private set; } | ||
135 | public static float AvatarFriction { get; private set; } | 136 | public static float AvatarFriction { get; private set; } |
136 | public static float AvatarStandingFriction { get; private set; } | 137 | public static float AvatarStandingFriction { get; private set; } |
137 | public static float AvatarAlwaysRunFactor { get; private set; } | 138 | public static float AvatarAlwaysRunFactor { get; private set; } |
@@ -571,6 +572,8 @@ public static class BSParam | |||
571 | new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" , | 572 | new ParameterDefn<float>("TerrainCollisionMargin", "Margin where collision checking starts" , |
572 | 0.04f ), | 573 | 0.04f ), |
573 | 574 | ||
575 | new ParameterDefn<bool>("AvatarToAvatarCollisionsByDefault", "Should avatars collide with other avatars by default?", | ||
576 | true), | ||
574 | new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", | 577 | new ParameterDefn<float>("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", |
575 | 0.2f ), | 578 | 0.2f ), |
576 | new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", | 579 | new ParameterDefn<float>("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index a46c241..0f79a10 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -130,6 +130,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
130 | internal int m_maxUpdatesPerFrame; | 130 | internal int m_maxUpdatesPerFrame; |
131 | internal EntityProperties[] m_updateArray; | 131 | internal EntityProperties[] m_updateArray; |
132 | 132 | ||
133 | /// <summary> | ||
134 | /// Used to control physics simulation timing if Bullet is running on its own thread. | ||
135 | /// </summary> | ||
136 | private ManualResetEvent m_updateWaitEvent; | ||
137 | |||
133 | public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero | 138 | public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero |
134 | public const uint GROUNDPLANE_ID = 1; | 139 | public const uint GROUNDPLANE_ID = 1; |
135 | public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here | 140 | public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here |
@@ -288,7 +293,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
288 | { | 293 | { |
289 | // The physics simulation should happen independently of the heartbeat loop | 294 | // The physics simulation should happen independently of the heartbeat loop |
290 | m_physicsThread | 295 | m_physicsThread |
291 | = Watchdog.StartThread( | 296 | = WorkManager.StartThread( |
292 | BulletSPluginPhysicsThread, | 297 | BulletSPluginPhysicsThread, |
293 | string.Format("{0} ({1})", BulletEngineName, RegionName), | 298 | string.Format("{0} ({1})", BulletEngineName, RegionName), |
294 | ThreadPriority.Normal, | 299 | ThreadPriority.Normal, |
@@ -838,6 +843,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
838 | 843 | ||
839 | public void BulletSPluginPhysicsThread() | 844 | public void BulletSPluginPhysicsThread() |
840 | { | 845 | { |
846 | Thread.CurrentThread.Priority = ThreadPriority.Highest; | ||
847 | m_updateWaitEvent = new ManualResetEvent(false); | ||
848 | |||
841 | while (m_initialized) | 849 | while (m_initialized) |
842 | { | 850 | { |
843 | int beginSimulationRealtimeMS = Util.EnvironmentTickCount(); | 851 | int beginSimulationRealtimeMS = Util.EnvironmentTickCount(); |
@@ -851,8 +859,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
851 | if (simulationTimeVsRealtimeDifferenceMS > 0) | 859 | if (simulationTimeVsRealtimeDifferenceMS > 0) |
852 | { | 860 | { |
853 | // The simulation of the time interval took less than realtime. | 861 | // The simulation of the time interval took less than realtime. |
854 | // Do a sleep for the rest of realtime. | 862 | // Do a wait for the rest of realtime. |
855 | Thread.Sleep(simulationTimeVsRealtimeDifferenceMS); | 863 | m_updateWaitEvent.WaitOne(simulationTimeVsRealtimeDifferenceMS); |
864 | //Thread.Sleep(simulationTimeVsRealtimeDifferenceMS); | ||
856 | } | 865 | } |
857 | else | 866 | else |
858 | { | 867 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs index 3425d9e..5932461 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs | |||
@@ -190,6 +190,7 @@ public class BulletHMapInfo | |||
190 | public enum CollisionType | 190 | public enum CollisionType |
191 | { | 191 | { |
192 | Avatar, | 192 | Avatar, |
193 | PhantomToOthersAvatar, // An avatar that it phantom to other avatars but not to anything else | ||
193 | Groundplane, | 194 | Groundplane, |
194 | Terrain, | 195 | Terrain, |
195 | Static, | 196 | Static, |
@@ -231,7 +232,12 @@ public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeM | |||
231 | { CollisionType.Avatar, | 232 | { CollisionType.Avatar, |
232 | new CollisionTypeFilterGroup(CollisionType.Avatar, | 233 | new CollisionTypeFilterGroup(CollisionType.Avatar, |
233 | (uint)CollisionFilterGroups.BCharacterGroup, | 234 | (uint)CollisionFilterGroups.BCharacterGroup, |
234 | (uint)CollisionFilterGroups.BAllGroup) | 235 | (uint)(CollisionFilterGroups.BAllGroup)) |
236 | }, | ||
237 | { CollisionType.PhantomToOthersAvatar, | ||
238 | new CollisionTypeFilterGroup(CollisionType.PhantomToOthersAvatar, | ||
239 | (uint)CollisionFilterGroups.BCharacterGroup, | ||
240 | (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BCharacterGroup)) | ||
235 | }, | 241 | }, |
236 | { CollisionType.Groundplane, | 242 | { CollisionType.Groundplane, |
237 | new CollisionTypeFilterGroup(CollisionType.Groundplane, | 243 | new CollisionTypeFilterGroup(CollisionType.Groundplane, |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index e347fdc..f5a25d6 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -3343,7 +3343,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
3343 | RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod; | 3343 | RequestAssetDelegate assetProvider = _parent_scene.RequestAssetMethod; |
3344 | if (assetProvider != null) | 3344 | if (assetProvider != null) |
3345 | assetProvider(_pbs.SculptTexture, MeshAssetReceived); | 3345 | assetProvider(_pbs.SculptTexture, MeshAssetReceived); |
3346 | }); | 3346 | }, null, "ODEPrim.CheckMeshAsset"); |
3347 | } | 3347 | } |
3348 | } | 3348 | } |
3349 | 3349 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index 40a05cf..036cb5d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs | |||
@@ -182,7 +182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
182 | { | 182 | { |
183 | // Start the thread that will be doing the work | 183 | // Start the thread that will be doing the work |
184 | cmdHandlerThread | 184 | cmdHandlerThread |
185 | = Watchdog.StartThread( | 185 | = WorkManager.StartThread( |
186 | CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true); | 186 | CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true); |
187 | } | 187 | } |
188 | } | 188 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e7ba7a4..97e3eeb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2979,7 +2979,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2979 | 2979 | ||
2980 | money.ObjectGiveMoney( | 2980 | money.ObjectGiveMoney( |
2981 | m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); | 2981 | m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); |
2982 | }); | 2982 | }, null, "LSL_Api.llGiveMoney"); |
2983 | } | 2983 | } |
2984 | 2984 | ||
2985 | public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) | 2985 | public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) |
@@ -3075,7 +3075,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3075 | } | 3075 | } |
3076 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | 3076 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) |
3077 | } | 3077 | } |
3078 | }); | 3078 | }, null, "LSL_Api.llRezAtRoot"); |
3079 | 3079 | ||
3080 | //ScriptSleep((int)((groupmass * velmag) / 10)); | 3080 | //ScriptSleep((int)((groupmass * velmag) / 10)); |
3081 | ScriptSleep(100); | 3081 | ScriptSleep(100); |
@@ -3270,7 +3270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3270 | /// </remarks> | 3270 | /// </remarks> |
3271 | public void DetachFromAvatar() | 3271 | public void DetachFromAvatar() |
3272 | { | 3272 | { |
3273 | Util.FireAndForget(DetachWrapper, m_host); | 3273 | Util.FireAndForget(DetachWrapper, m_host, "LSL_Api.DetachFromAvatar"); |
3274 | } | 3274 | } |
3275 | 3275 | ||
3276 | private void DetachWrapper(object o) | 3276 | private void DetachWrapper(object o) |
@@ -12421,7 +12421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12421 | new LSL_String(replydata) }, | 12421 | new LSL_String(replydata) }, |
12422 | new DetectParams[0])); | 12422 | new DetectParams[0])); |
12423 | } | 12423 | } |
12424 | }); | 12424 | }, null, "LSL_Api.llTransferLindenDollars"); |
12425 | 12425 | ||
12426 | return txn.ToString(); | 12426 | return txn.ToString(); |
12427 | } | 12427 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 704ff15..10ddf14 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -790,9 +790,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
790 | 790 | ||
791 | // We will launch the teleport on a new thread so that when the script threads are terminated | 791 | // We will launch the teleport on a new thread so that when the script threads are terminated |
792 | // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. | 792 | // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. |
793 | Util.FireAndForget(o => World.RequestTeleportLocation( | 793 | Util.FireAndForget( |
794 | presence.ControllingClient, regionName, position, | 794 | o => World.RequestTeleportLocation( |
795 | lookat, (uint)TPFlags.ViaLocation)); | 795 | presence.ControllingClient, regionName, position, |
796 | lookat, (uint)TPFlags.ViaLocation), | ||
797 | null, "OSSL_Api.TeleportAgentByRegionCoords"); | ||
796 | 798 | ||
797 | ScriptSleep(5000); | 799 | ScriptSleep(5000); |
798 | 800 | ||
@@ -836,9 +838,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
836 | 838 | ||
837 | // We will launch the teleport on a new thread so that when the script threads are terminated | 839 | // We will launch the teleport on a new thread so that when the script threads are terminated |
838 | // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. | 840 | // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. |
839 | Util.FireAndForget(o => World.RequestTeleportLocation( | 841 | Util.FireAndForget( |
840 | presence.ControllingClient, regionHandle, | 842 | o => World.RequestTeleportLocation( |
841 | position, lookat, (uint)TPFlags.ViaLocation)); | 843 | presence.ControllingClient, regionHandle, |
844 | position, lookat, (uint)TPFlags.ViaLocation), | ||
845 | null, "OSSL_Api.TeleportAgentByRegionName"); | ||
842 | 846 | ||
843 | ScriptSleep(5000); | 847 | ScriptSleep(5000); |
844 | 848 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index ac822c6..1fff6ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Region.Framework.Scenes; | |||
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.ScriptEngine.XEngine; | 38 | using OpenSim.Region.ScriptEngine.XEngine; |
39 | using OpenSim.Tests.Common; | 39 | using OpenSim.Tests.Common; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests | 41 | namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests |
43 | { | 42 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs index 1415925..8170e9b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; | |||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | 48 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; |
50 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | 49 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; |
51 | 50 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs index ab44e38..14e45ff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api; | |||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 49 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
51 | { | 50 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs index 1ad0a99..9fd8532 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs | |||
@@ -44,7 +44,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api; | |||
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 44 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
45 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | using PermissionMask = OpenSim.Framework.PermissionMask; | 47 | using PermissionMask = OpenSim.Framework.PermissionMask; |
49 | 48 | ||
50 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 49 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
@@ -248,15 +247,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
248 | UUID user1Id = TestHelpers.ParseTail(0x1); | 247 | UUID user1Id = TestHelpers.ParseTail(0x1); |
249 | UUID user2Id = TestHelpers.ParseTail(0x2); | 248 | UUID user2Id = TestHelpers.ParseTail(0x2); |
250 | 249 | ||
251 | SceneObjectGroup sourceSo = SceneHelpers.AddSceneObject(m_scene, 1, user1Id, "sourceSo", 0x10); | 250 | SceneObjectGroup sourceSo = SceneHelpers.AddSceneObject(m_scene, "sourceSo", user1Id); |
252 | m_scene.AddSceneObject(sourceSo); | 251 | m_scene.AddSceneObject(sourceSo); |
253 | LSL_Api api = new LSL_Api(); | 252 | LSL_Api api = new LSL_Api(); |
254 | api.Initialize(m_engine, sourceSo.RootPart, null, null); | 253 | api.Initialize(m_engine, sourceSo.RootPart, null, null); |
255 | TaskInventoryHelpers.AddScript(m_scene, sourceSo.RootPart, "script", "Hello World"); | 254 | TaskInventoryHelpers.AddScript(m_scene, sourceSo.RootPart, "script", "Hello World"); |
256 | 255 | ||
257 | SceneObjectGroup targetSo = SceneHelpers.AddSceneObject(m_scene, 1, user1Id, "targetSo", 0x20); | 256 | SceneObjectGroup targetSo = SceneHelpers.AddSceneObject(m_scene, "targetSo", user1Id); |
258 | SceneObjectGroup otherOwnedTargetSo | 257 | SceneObjectGroup otherOwnedTargetSo = SceneHelpers.AddSceneObject(m_scene, "otherOwnedTargetSo", user2Id); |
259 | = SceneHelpers.AddSceneObject(m_scene, 1, user2Id, "otherOwnedTargetSo", 0x30); | ||
260 | 258 | ||
261 | // Test that we cannot load a script when the target pin has never been set (i.e. it is zero) | 259 | // Test that we cannot load a script when the target pin has never been set (i.e. it is zero) |
262 | api.llRemoteLoadScriptPin(targetSo.UUID.ToString(), "script", 0, 0, 0); | 260 | api.llRemoteLoadScriptPin(targetSo.UUID.ToString(), "script", 0, 0, 0); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs index 4c5a501..f347869 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; | |||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 49 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
51 | { | 50 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs index 60de5cb..0b1ae60 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api; | |||
37 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 37 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
38 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 38 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
39 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | 41 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; |
43 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | 42 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs index 42d1b3b..b9028ab 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiNotecardTests.cs | |||
@@ -18,7 +18,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api; | |||
18 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 18 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
19 | using OpenSim.Services.Interfaces; | 19 | using OpenSim.Services.Interfaces; |
20 | using OpenSim.Tests.Common; | 20 | using OpenSim.Tests.Common; |
21 | using OpenSim.Tests.Common.Mock; | ||
22 | 21 | ||
23 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 22 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
24 | { | 23 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs index ed61dc0..d7651e3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiObjectTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; | |||
45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 45 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
46 | using OpenSim.Services.Interfaces; | 46 | using OpenSim.Services.Interfaces; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | 48 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; |
50 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | 49 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; |
51 | 50 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 7e3726a..1b7aa63 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs | |||
@@ -37,7 +37,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; | |||
37 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 37 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
38 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using System; | 39 | using System; |
40 | using OpenSim.Tests.Common.Mock; | ||
41 | 40 | ||
42 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 41 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
43 | { | 42 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs index c88bad5..4c31969 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs | |||
@@ -44,7 +44,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api; | |||
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 44 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
45 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | 47 | ||
49 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 48 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
50 | { | 49 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs index e422f5b..caba4a4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | |||
@@ -44,7 +44,6 @@ using OpenSim.Region.ScriptEngine.Shared.Api; | |||
44 | using OpenSim.Region.ScriptEngine.Shared.Instance; | 44 | using OpenSim.Region.ScriptEngine.Shared.Instance; |
45 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 46 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | 47 | ||
49 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 48 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
50 | { | 49 | { |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs index 495e684..398ccbe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | |||
@@ -46,7 +46,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance; | |||
46 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 46 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
47 | using OpenSim.Services.Interfaces; | 47 | using OpenSim.Services.Interfaces; |
48 | using OpenSim.Tests.Common; | 48 | using OpenSim.Tests.Common; |
49 | using OpenSim.Tests.Common.Mock; | ||
50 | 49 | ||
51 | namespace OpenSim.Region.ScriptEngine.Shared.Tests | 50 | namespace OpenSim.Region.ScriptEngine.Shared.Tests |
52 | { | 51 | { |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs index bafcdd8..fe15157 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineBasicTests.cs | |||
@@ -36,7 +36,6 @@ using OpenSim.Region.CoreModules.Scripting.WorldComm; | |||
36 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
37 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Tests.Common; | 38 | using OpenSim.Tests.Common; |
39 | using OpenSim.Tests.Common.Mock; | ||
40 | 39 | ||
41 | namespace OpenSim.Region.ScriptEngine.XEngine.Tests | 40 | namespace OpenSim.Region.ScriptEngine.XEngine.Tests |
42 | { | 41 | { |
diff --git a/OpenSim/Server/Base/HttpServerBase.cs b/OpenSim/Server/Base/HttpServerBase.cs index 954783c..44ef124 100644 --- a/OpenSim/Server/Base/HttpServerBase.cs +++ b/OpenSim/Server/Base/HttpServerBase.cs | |||
@@ -56,15 +56,16 @@ namespace OpenSim.Server.Base | |||
56 | 56 | ||
57 | if (networkConfig == null) | 57 | if (networkConfig == null) |
58 | { | 58 | { |
59 | System.Console.WriteLine("Section 'Network' not found, server can't start"); | 59 | System.Console.WriteLine("ERROR: Section [Network] not found, server can't start"); |
60 | Thread.CurrentThread.Abort(); | 60 | Environment.Exit(1); |
61 | } | 61 | } |
62 | 62 | ||
63 | uint port = (uint)networkConfig.GetInt("port", 0); | 63 | uint port = (uint)networkConfig.GetInt("port", 0); |
64 | 64 | ||
65 | if (port == 0) | 65 | if (port == 0) |
66 | { | 66 | { |
67 | Thread.CurrentThread.Abort(); | 67 | System.Console.WriteLine("ERROR: No 'port' entry found in [Network]. Server can't start"); |
68 | Environment.Exit(1); | ||
68 | } | 69 | } |
69 | 70 | ||
70 | bool ssl_main = networkConfig.GetBoolean("https_main",false); | 71 | bool ssl_main = networkConfig.GetBoolean("https_main",false); |
@@ -83,23 +84,24 @@ namespace OpenSim.Server.Base | |||
83 | // Then, check for https settings and ADD a server to | 84 | // Then, check for https settings and ADD a server to |
84 | // m_Servers | 85 | // m_Servers |
85 | // | 86 | // |
86 | if ( !ssl_main ) | 87 | if (!ssl_main) |
87 | { | 88 | { |
88 | httpServer = new BaseHttpServer(port); | 89 | httpServer = new BaseHttpServer(port); |
89 | } | 90 | } |
90 | else | 91 | else |
91 | { | 92 | { |
92 | string cert_path = networkConfig.GetString("cert_path",String.Empty); | 93 | string cert_path = networkConfig.GetString("cert_path",String.Empty); |
93 | if ( cert_path == String.Empty ) | 94 | if (cert_path == String.Empty) |
94 | { | 95 | { |
95 | System.Console.WriteLine("Path to X509 certificate is missing, server can't start."); | 96 | System.Console.WriteLine("ERROR: Path to X509 certificate is missing, server can't start."); |
96 | Thread.CurrentThread.Abort(); | 97 | Environment.Exit(1); |
97 | } | 98 | } |
99 | |||
98 | string cert_pass = networkConfig.GetString("cert_pass",String.Empty); | 100 | string cert_pass = networkConfig.GetString("cert_pass",String.Empty); |
99 | if ( cert_pass == String.Empty ) | 101 | if (cert_pass == String.Empty) |
100 | { | 102 | { |
101 | System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); | 103 | System.Console.WriteLine("ERROR: Password for X509 certificate is missing, server can't start."); |
102 | Thread.CurrentThread.Abort(); | 104 | Environment.Exit(1); |
103 | } | 105 | } |
104 | 106 | ||
105 | httpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); | 107 | httpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass); |
@@ -109,21 +111,22 @@ namespace OpenSim.Server.Base | |||
109 | MainServer.Instance = httpServer; | 111 | MainServer.Instance = httpServer; |
110 | 112 | ||
111 | // If https_listener = true, then add an ssl listener on the https_port... | 113 | // If https_listener = true, then add an ssl listener on the https_port... |
112 | if ( ssl_listener == true ) { | 114 | if (ssl_listener == true) |
113 | 115 | { | |
114 | uint https_port = (uint)networkConfig.GetInt("https_port", 0); | 116 | uint https_port = (uint)networkConfig.GetInt("https_port", 0); |
115 | 117 | ||
116 | string cert_path = networkConfig.GetString("cert_path",String.Empty); | 118 | string cert_path = networkConfig.GetString("cert_path",String.Empty); |
117 | if ( cert_path == String.Empty ) | 119 | if (cert_path == String.Empty) |
118 | { | 120 | { |
119 | System.Console.WriteLine("Path to X509 certificate is missing, server can't start."); | 121 | System.Console.WriteLine("ERROR: Path to X509 certificate is missing, server can't start."); |
120 | Thread.CurrentThread.Abort(); | 122 | Environment.Exit(1); |
121 | } | 123 | } |
124 | |||
122 | string cert_pass = networkConfig.GetString("cert_pass",String.Empty); | 125 | string cert_pass = networkConfig.GetString("cert_pass",String.Empty); |
123 | if ( cert_pass == String.Empty ) | 126 | if (cert_pass == String.Empty) |
124 | { | 127 | { |
125 | System.Console.WriteLine("Password for X509 certificate is missing, server can't start."); | 128 | System.Console.WriteLine("ERROR: Password for X509 certificate is missing, server can't start."); |
126 | Thread.CurrentThread.Abort(); | 129 | Environment.Exit(1); |
127 | } | 130 | } |
128 | 131 | ||
129 | MainServer.AddHttpServer(new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass)); | 132 | MainServer.AddHttpServer(new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass)); |
diff --git a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs index 427fa16..faa6fb7 100644 --- a/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs +++ b/OpenSim/Server/Handlers/Asset/Tests/AssetServerPostHandlerTests.cs | |||
@@ -39,7 +39,6 @@ using OpenSim.Server.Handlers.Asset; | |||
39 | using OpenSim.Services.AssetService; | 39 | using OpenSim.Services.AssetService; |
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | using OpenSim.Tests.Common; | 41 | using OpenSim.Tests.Common; |
42 | using OpenSim.Tests.Common.Mock; | ||
43 | 42 | ||
44 | namespace OpenSim.Server.Handlers.Asset.Test | 43 | namespace OpenSim.Server.Handlers.Asset.Test |
45 | { | 44 | { |
diff --git a/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs b/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs index 9e703f1..3c61673 100644 --- a/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs +++ b/OpenSim/Server/Handlers/BakedTextures/XBakesGetHandler.cs | |||
@@ -45,7 +45,7 @@ namespace OpenSim.Server.Handlers.BakedTextures | |||
45 | { | 45 | { |
46 | public class BakesServerGetHandler : BaseStreamHandler | 46 | public class BakesServerGetHandler : BaseStreamHandler |
47 | { | 47 | { |
48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private IBakedTextureService m_BakesService; | 50 | private IBakedTextureService m_BakesService; |
51 | private System.Text.UTF8Encoding utf8 = | 51 | private System.Text.UTF8Encoding utf8 = |
diff --git a/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs b/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs index 1aacbc9..e38543b 100644 --- a/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs +++ b/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs | |||
@@ -45,13 +45,10 @@ namespace OpenSim.Server.Handlers.BakedTextures | |||
45 | { | 45 | { |
46 | public class BakesServerPostHandler : BaseStreamHandler | 46 | public class BakesServerPostHandler : BaseStreamHandler |
47 | { | 47 | { |
48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private IBakedTextureService m_BakesService; | 50 | private IBakedTextureService m_BakesService; |
51 | 51 | ||
52 | private System.Text.UTF8Encoding utf8 = | ||
53 | new System.Text.UTF8Encoding(); | ||
54 | |||
55 | public BakesServerPostHandler(IBakedTextureService service, IServiceAuth auth) : | 52 | public BakesServerPostHandler(IBakedTextureService service, IServiceAuth auth) : |
56 | base("POST", "/bakes", auth) | 53 | base("POST", "/bakes", auth) |
57 | { | 54 | { |
@@ -76,4 +73,4 @@ namespace OpenSim.Server.Handlers.BakedTextures | |||
76 | return new byte[0]; | 73 | return new byte[0]; |
77 | } | 74 | } |
78 | } | 75 | } |
79 | } | 76 | } \ No newline at end of file |
diff --git a/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs b/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs index f8f1d00..49aa8ba 100644 --- a/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs +++ b/OpenSim/Server/Handlers/Profiles/UserProfilesHandlers.cs | |||
@@ -263,8 +263,7 @@ namespace OpenSim.Server.Handlers | |||
263 | m_log.DebugFormat ("Avatar Notes Request"); | 263 | m_log.DebugFormat ("Avatar Notes Request"); |
264 | return false; | 264 | return false; |
265 | } | 265 | } |
266 | 266 | ||
267 | string result = string.Empty; | ||
268 | UserProfileNotes note = new UserProfileNotes(); | 267 | UserProfileNotes note = new UserProfileNotes(); |
269 | object Note = (object)note; | 268 | object Note = (object)note; |
270 | OSD.DeserializeMembers(ref Note, (OSDMap)json["params"]); | 269 | OSD.DeserializeMembers(ref Note, (OSDMap)json["params"]); |
@@ -403,7 +402,7 @@ namespace OpenSim.Server.Handlers | |||
403 | 402 | ||
404 | response.Error.Code = ErrorCode.InternalError; | 403 | response.Error.Code = ErrorCode.InternalError; |
405 | response.Error.Message = string.Format("{0}", result); | 404 | response.Error.Message = string.Format("{0}", result); |
406 | m_log.InfoFormat("[PROFILES]: User preferences request error - {0}", response.Error.Message); | 405 | // m_log.InfoFormat("[PROFILES]: User preferences request error - {0}", response.Error.Message); |
407 | return false; | 406 | return false; |
408 | } | 407 | } |
409 | 408 | ||
diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index da2bfeb..81c9df2 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | |||
@@ -182,7 +182,8 @@ namespace OpenSim.Server.Handlers.Simulation | |||
182 | if (action.Equals("release")) | 182 | if (action.Equals("release")) |
183 | ReleaseAgent(regionID, id); | 183 | ReleaseAgent(regionID, id); |
184 | else | 184 | else |
185 | Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id, auth_token); }); | 185 | Util.FireAndForget( |
186 | o => m_SimulationService.CloseAgent(destination, id, auth_token), null, "AgentHandler.DoAgentDelete"); | ||
186 | 187 | ||
187 | responsedata["int_response_code"] = HttpStatusCode.OK; | 188 | responsedata["int_response_code"] = HttpStatusCode.OK; |
188 | responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); | 189 | responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs index 95e4bab..cd4781d 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs | |||
@@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
69 | Util.FireAndForget(delegate(object o) | 69 | Util.FireAndForget(delegate(object o) |
70 | { | 70 | { |
71 | m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); | 71 | m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); |
72 | }); | 72 | }, null, "SimianActivityDetector.SetLastPositionOnMakeRootAgent"); |
73 | } | 73 | } |
74 | 74 | ||
75 | public void OnNewClient(IClientAPI client) | 75 | public void OnNewClient(IClientAPI client) |
@@ -94,7 +94,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
94 | Util.FireAndForget(delegate(object o) | 94 | Util.FireAndForget(delegate(object o) |
95 | { | 95 | { |
96 | m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); | 96 | m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); |
97 | }); | 97 | }, null, "SimianActivityDetector.SetLastPositionOnEnteringNewParcel"); |
98 | } | 98 | } |
99 | } | 99 | } |
100 | } \ No newline at end of file | 100 | } \ No newline at end of file |
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 01cbf91..9ad4a7a 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs | |||
@@ -225,7 +225,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
225 | { | 225 | { |
226 | AssetBase asset = SimianGetOperation(id); | 226 | AssetBase asset = SimianGetOperation(id); |
227 | handler(id, sender, asset); | 227 | handler(id, sender, asset); |
228 | } | 228 | }, null, "SimianAssetServiceConnector.GetFromService" |
229 | ); | 229 | ); |
230 | 230 | ||
231 | return true; | 231 | return true; |
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs index 5c804d4..b57f8d8 100644 --- a/OpenSim/Services/HypergridService/HGAssetService.cs +++ b/OpenSim/Services/HypergridService/HGAssetService.cs | |||
@@ -100,7 +100,7 @@ namespace OpenSim.Services.HypergridService | |||
100 | return null; | 100 | return null; |
101 | 101 | ||
102 | if (asset.Metadata.Type == (sbyte)AssetType.Object) | 102 | if (asset.Metadata.Type == (sbyte)AssetType.Object) |
103 | asset.Data = AdjustIdentifiers(asset.Data); ; | 103 | asset.Data = AdjustIdentifiers(asset.Data); |
104 | 104 | ||
105 | AdjustIdentifiers(asset.Metadata); | 105 | AdjustIdentifiers(asset.Metadata); |
106 | 106 | ||
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs index a8bcfb2..6e35a88 100644 --- a/OpenSim/Services/HypergridService/HGFriendsService.cs +++ b/OpenSim/Services/HypergridService/HGFriendsService.cs | |||
@@ -198,7 +198,8 @@ namespace OpenSim.Services.HypergridService | |||
198 | // So let's send back the call, but start a thread to continue | 198 | // So let's send back the call, but start a thread to continue |
199 | // with the verification and the actual action. | 199 | // with the verification and the actual action. |
200 | 200 | ||
201 | Util.FireAndForget(delegate { ProcessFriendshipOffered(fromID, fromName, toID, message); }); | 201 | Util.FireAndForget( |
202 | o => ProcessFriendshipOffered(fromID, fromName, toID, message), null, "HGFriendsService.ProcessFriendshipOffered"); | ||
202 | 203 | ||
203 | return true; | 204 | return true; |
204 | } | 205 | } |
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index c45ea76..ce50ab0 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs | |||
@@ -126,7 +126,7 @@ namespace OpenSim.Services.Interfaces | |||
126 | 126 | ||
127 | public class GridRegion | 127 | public class GridRegion |
128 | { | 128 | { |
129 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 129 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
130 | 130 | ||
131 | #pragma warning disable 414 | 131 | #pragma warning disable 414 |
132 | private static readonly string LogHeader = "[GRID REGION]"; | 132 | private static readonly string LogHeader = "[GRID REGION]"; |
@@ -135,12 +135,7 @@ namespace OpenSim.Services.Interfaces | |||
135 | /// <summary> | 135 | /// <summary> |
136 | /// The port by which http communication occurs with the region | 136 | /// The port by which http communication occurs with the region |
137 | /// </summary> | 137 | /// </summary> |
138 | public uint HttpPort | 138 | public uint HttpPort { get; set; } |
139 | { | ||
140 | get { return m_httpPort; } | ||
141 | set { m_httpPort = value; } | ||
142 | } | ||
143 | protected uint m_httpPort; | ||
144 | 139 | ||
145 | /// <summary> | 140 | /// <summary> |
146 | /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) | 141 | /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) |
@@ -151,10 +146,10 @@ namespace OpenSim.Services.Interfaces | |||
151 | if (!String.IsNullOrEmpty(m_serverURI)) { | 146 | if (!String.IsNullOrEmpty(m_serverURI)) { |
152 | return m_serverURI; | 147 | return m_serverURI; |
153 | } else { | 148 | } else { |
154 | if (m_httpPort == 0) | 149 | if (HttpPort == 0) |
155 | return "http://" + m_externalHostName + "/"; | 150 | return "http://" + m_externalHostName + "/"; |
156 | else | 151 | else |
157 | return "http://" + m_externalHostName + ":" + m_httpPort + "/"; | 152 | return "http://" + m_externalHostName + ":" + HttpPort + "/"; |
158 | } | 153 | } |
159 | } | 154 | } |
160 | set { | 155 | set { |
@@ -290,7 +285,7 @@ namespace OpenSim.Services.Interfaces | |||
290 | RegionSizeY = (int)ConvertFrom.RegionSizeY; | 285 | RegionSizeY = (int)ConvertFrom.RegionSizeY; |
291 | m_internalEndPoint = ConvertFrom.InternalEndPoint; | 286 | m_internalEndPoint = ConvertFrom.InternalEndPoint; |
292 | m_externalHostName = ConvertFrom.ExternalHostName; | 287 | m_externalHostName = ConvertFrom.ExternalHostName; |
293 | m_httpPort = ConvertFrom.HttpPort; | 288 | HttpPort = ConvertFrom.HttpPort; |
294 | RegionID = ConvertFrom.RegionID; | 289 | RegionID = ConvertFrom.RegionID; |
295 | ServerURI = ConvertFrom.ServerURI; | 290 | ServerURI = ConvertFrom.ServerURI; |
296 | TerrainImage = ConvertFrom.RegionSettings.TerrainImageID; | 291 | TerrainImage = ConvertFrom.RegionSettings.TerrainImageID; |
@@ -310,7 +305,7 @@ namespace OpenSim.Services.Interfaces | |||
310 | RegionSizeY = ConvertFrom.RegionSizeY; | 305 | RegionSizeY = ConvertFrom.RegionSizeY; |
311 | m_internalEndPoint = ConvertFrom.InternalEndPoint; | 306 | m_internalEndPoint = ConvertFrom.InternalEndPoint; |
312 | m_externalHostName = ConvertFrom.ExternalHostName; | 307 | m_externalHostName = ConvertFrom.ExternalHostName; |
313 | m_httpPort = ConvertFrom.HttpPort; | 308 | HttpPort = ConvertFrom.HttpPort; |
314 | RegionID = ConvertFrom.RegionID; | 309 | RegionID = ConvertFrom.RegionID; |
315 | ServerURI = ConvertFrom.ServerURI; | 310 | ServerURI = ConvertFrom.ServerURI; |
316 | TerrainImage = ConvertFrom.TerrainImage; | 311 | TerrainImage = ConvertFrom.TerrainImage; |
diff --git a/OpenSim/Services/Interfaces/OpenProfileClient.cs b/OpenSim/Services/Interfaces/OpenProfileClient.cs index e601ebe..bda8151 100644 --- a/OpenSim/Services/Interfaces/OpenProfileClient.cs +++ b/OpenSim/Services/Interfaces/OpenProfileClient.cs | |||
@@ -48,7 +48,7 @@ namespace OpenSim.Services.UserProfilesService | |||
48 | /// </remarks> | 48 | /// </remarks> |
49 | public class OpenProfileClient | 49 | public class OpenProfileClient |
50 | { | 50 | { |
51 | static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | private string m_serverURI; | 53 | private string m_serverURI; |
54 | 54 | ||
@@ -60,8 +60,7 @@ namespace OpenSim.Services.UserProfilesService | |||
60 | { | 60 | { |
61 | m_serverURI = serverURI; | 61 | m_serverURI = serverURI; |
62 | } | 62 | } |
63 | 63 | ||
64 | |||
65 | /// <summary> | 64 | /// <summary> |
66 | /// Gets an avatar's profile using the OpenProfile protocol. | 65 | /// Gets an avatar's profile using the OpenProfile protocol. |
67 | /// </summary> | 66 | /// </summary> |
@@ -132,4 +131,4 @@ namespace OpenSim.Services.UserProfilesService | |||
132 | return true; | 131 | return true; |
133 | } | 132 | } |
134 | } | 133 | } |
135 | } | 134 | } \ No newline at end of file |
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs index c07e034..a816411 100644 --- a/OpenSim/Services/MapImageService/MapImageService.cs +++ b/OpenSim/Services/MapImageService/MapImageService.cs | |||
@@ -166,7 +166,8 @@ namespace OpenSim.Services.MapImageService | |||
166 | // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y); | 166 | // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y); |
167 | multiRezToBuild.Enqueue(new mapToMultiRez(x, y)); | 167 | multiRezToBuild.Enqueue(new mapToMultiRez(x, y)); |
168 | if (multiRezToBuild.Count == 1) | 168 | if (multiRezToBuild.Count == 1) |
169 | Util.FireAndForget(DoUpdateMultiResolutionFilesAsync); | 169 | Util.FireAndForget( |
170 | DoUpdateMultiResolutionFilesAsync, null, "MapImageService.DoUpdateMultiResolutionFilesAsync"); | ||
170 | } | 171 | } |
171 | 172 | ||
172 | return true; | 173 | return true; |
diff --git a/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs b/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs index 49c99c5..82ecf9a 100644 --- a/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/BaseRequestHandlerHelpers.cs | |||
@@ -32,7 +32,6 @@ using NUnit.Framework; | |||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Servers; | 33 | using OpenSim.Framework.Servers; |
34 | using OpenSim.Framework.Servers.HttpServer; | 34 | using OpenSim.Framework.Servers.HttpServer; |
35 | using OpenSim.Tests.Common.Mock; | ||
36 | 35 | ||
37 | namespace OpenSim.Tests.Common | 36 | namespace OpenSim.Tests.Common |
38 | { | 37 | { |
diff --git a/OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs b/OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs new file mode 100644 index 0000000..33cd8a2 --- /dev/null +++ b/OpenSim/Tests/Common/Helpers/ClientStackHelpers.cs | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Net; | ||
30 | using Nini.Config; | ||
31 | using OpenMetaverse; | ||
32 | using OpenMetaverse.Packets; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Region.ClientStack.LindenUDP; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | |||
37 | namespace OpenSim.Tests.Common | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// This class adds full UDP client classes and associated scene presence to scene. | ||
41 | /// </summary> | ||
42 | /// <remarks> | ||
43 | /// This is used for testing client stack code. For testing other code, use SceneHelper methods instead since | ||
44 | /// they operate without the burden of setting up UDP structures which should be unnecessary for testing scene | ||
45 | /// code. | ||
46 | /// </remarks> | ||
47 | public static class ClientStackHelpers | ||
48 | { | ||
49 | public static ScenePresence AddChildClient( | ||
50 | Scene scene, LLUDPServer udpServer, UUID agentId, UUID sessionId, uint circuitCode) | ||
51 | { | ||
52 | IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); | ||
53 | |||
54 | UseCircuitCodePacket uccp = new UseCircuitCodePacket(); | ||
55 | |||
56 | UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock | ||
57 | = new UseCircuitCodePacket.CircuitCodeBlock(); | ||
58 | uccpCcBlock.Code = circuitCode; | ||
59 | uccpCcBlock.ID = agentId; | ||
60 | uccpCcBlock.SessionID = sessionId; | ||
61 | uccp.CircuitCode = uccpCcBlock; | ||
62 | |||
63 | byte[] uccpBytes = uccp.ToBytes(); | ||
64 | UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length); | ||
65 | upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. | ||
66 | Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); | ||
67 | |||
68 | AgentCircuitData acd = new AgentCircuitData(); | ||
69 | acd.AgentID = agentId; | ||
70 | acd.SessionID = sessionId; | ||
71 | |||
72 | scene.AuthenticateHandler.AddNewCircuit(circuitCode, acd); | ||
73 | |||
74 | udpServer.PacketReceived(upb); | ||
75 | |||
76 | return scene.GetScenePresence(agentId); | ||
77 | } | ||
78 | |||
79 | public static TestLLUDPServer AddUdpServer(Scene scene) | ||
80 | { | ||
81 | return AddUdpServer(scene, new IniConfigSource()); | ||
82 | } | ||
83 | |||
84 | public static TestLLUDPServer AddUdpServer(Scene scene, IniConfigSource configSource) | ||
85 | { | ||
86 | uint port = 0; | ||
87 | AgentCircuitManager acm = scene.AuthenticateHandler; | ||
88 | |||
89 | TestLLUDPServer udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm); | ||
90 | udpServer.AddScene(scene); | ||
91 | |||
92 | return udpServer; | ||
93 | } | ||
94 | } | ||
95 | } \ No newline at end of file | ||
diff --git a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs index 049200c..cf7583e 100644 --- a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.CoreModules.Framework; | 44 | using OpenSim.Region.CoreModules.Framework; |
45 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
46 | using OpenSim.Tests.Common.Mock; | ||
47 | 46 | ||
48 | namespace OpenSim.Tests.Common | 47 | namespace OpenSim.Tests.Common |
49 | { | 48 | { |
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 4369659..1fb1c5c 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs | |||
@@ -49,7 +49,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid; | |||
49 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts; | 49 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts; |
50 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; | 50 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence; |
51 | using OpenSim.Services.Interfaces; | 51 | using OpenSim.Services.Interfaces; |
52 | using OpenSim.Tests.Common.Mock; | ||
53 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 52 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
54 | 53 | ||
55 | namespace OpenSim.Tests.Common | 54 | namespace OpenSim.Tests.Common |
diff --git a/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs b/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs index e6e08cd..cb4fb80 100644 --- a/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs +++ b/OpenSim/Tests/Common/Mock/BaseAssetRepository.cs | |||
@@ -30,7 +30,7 @@ using System.Collections.Generic; | |||
30 | using OpenMetaverse; | 30 | using OpenMetaverse; |
31 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
32 | 32 | ||
33 | namespace OpenSim.Tests.Common.Mock | 33 | namespace OpenSim.Tests.Common |
34 | { | 34 | { |
35 | public class BaseAssetRepository | 35 | public class BaseAssetRepository |
36 | { | 36 | { |
diff --git a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs index 4a15cf2..dddf75d 100644 --- a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs | |||
@@ -31,7 +31,7 @@ using OpenMetaverse; | |||
31 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
32 | using OpenSim.Data; | 32 | using OpenSim.Data; |
33 | 33 | ||
34 | namespace OpenSim.Tests.Common.Mock | 34 | namespace OpenSim.Tests.Common |
35 | { | 35 | { |
36 | /// <summary> | 36 | /// <summary> |
37 | /// In memory asset data plugin for test purposes. Could be another dll when properly filled out and when the | 37 | /// In memory asset data plugin for test purposes. Could be another dll when properly filled out and when the |
diff --git a/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs b/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs index 5a257e9..7f530d0 100644 --- a/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs +++ b/OpenSim/Tests/Common/Mock/MockGroupsServicesConnector.cs | |||
@@ -40,7 +40,7 @@ using OpenSim.Region.Framework.Interfaces; | |||
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; | 41 | using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; |
42 | 42 | ||
43 | namespace OpenSim.Tests.Common.Mock | 43 | namespace OpenSim.Tests.Common |
44 | { | 44 | { |
45 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] | 45 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] |
46 | public class MockGroupsServicesConnector : ISharedRegionModule, IGroupsServicesConnector | 46 | public class MockGroupsServicesConnector : ISharedRegionModule, IGroupsServicesConnector |
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 8eeaf99..0e1bc8f 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -38,7 +38,7 @@ using OpenSim.Region.Framework.Interfaces; | |||
38 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
39 | using OpenSim.Framework.Client; | 39 | using OpenSim.Framework.Client; |
40 | 40 | ||
41 | namespace OpenSim.Tests.Common.Mock | 41 | namespace OpenSim.Tests.Common |
42 | { | 42 | { |
43 | public class TestClient : IClientAPI, IClientCore | 43 | public class TestClient : IClientAPI, IClientCore |
44 | { | 44 | { |
diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index fc44358..a8883b8 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs | |||
@@ -33,7 +33,7 @@ using OpenMetaverse; | |||
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Data; | 34 | using OpenSim.Data; |
35 | 35 | ||
36 | namespace OpenSim.Tests.Common.Mock | 36 | namespace OpenSim.Tests.Common |
37 | { | 37 | { |
38 | /// <summary> | 38 | /// <summary> |
39 | /// In memory inventory data plugin for test purposes. Could be another dll when properly filled out and when the | 39 | /// In memory inventory data plugin for test purposes. Could be another dll when properly filled out and when the |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs b/OpenSim/Tests/Common/Mock/TestLLUDPServer.cs index 27b9e5b..26887c9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs +++ b/OpenSim/Tests/Common/Mock/TestLLUDPServer.cs | |||
@@ -32,8 +32,9 @@ using System.Net.Sockets; | |||
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenMetaverse.Packets; | 33 | using OpenMetaverse.Packets; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.ClientStack.LindenUDP; | ||
35 | 36 | ||
36 | namespace OpenSim.Region.ClientStack.LindenUDP.Tests | 37 | namespace OpenSim.Tests.Common |
37 | { | 38 | { |
38 | /// <summary> | 39 | /// <summary> |
39 | /// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data. | 40 | /// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data. |
diff --git a/OpenSim/Tests/Common/Mock/TestLandChannel.cs b/OpenSim/Tests/Common/Mock/TestLandChannel.cs index 3115035..89ebcd5 100644 --- a/OpenSim/Tests/Common/Mock/TestLandChannel.cs +++ b/OpenSim/Tests/Common/Mock/TestLandChannel.cs | |||
@@ -32,7 +32,7 @@ using OpenSim.Region.Framework.Interfaces; | |||
32 | using OpenSim.Region.Framework.Scenes; | 32 | using OpenSim.Region.Framework.Scenes; |
33 | using OpenSim.Region.CoreModules.World.Land; | 33 | using OpenSim.Region.CoreModules.World.Land; |
34 | 34 | ||
35 | namespace OpenSim.Tests.Common.Mock | 35 | namespace OpenSim.Tests.Common |
36 | { | 36 | { |
37 | /// <summary> | 37 | /// <summary> |
38 | /// Land channel for test purposes | 38 | /// Land channel for test purposes |
diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs index e769d30..7b1d2b5 100644 --- a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs +++ b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs | |||
@@ -35,7 +35,7 @@ using System.Text; | |||
35 | using System.Web; | 35 | using System.Web; |
36 | using OpenSim.Framework.Servers.HttpServer; | 36 | using OpenSim.Framework.Servers.HttpServer; |
37 | 37 | ||
38 | namespace OpenSim.Tests.Common.Mock | 38 | namespace OpenSim.Tests.Common |
39 | { | 39 | { |
40 | public class TestOSHttpRequest : IOSHttpRequest | 40 | public class TestOSHttpRequest : IOSHttpRequest |
41 | { | 41 | { |
diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs b/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs index e10fe82..2e17f1e 100644 --- a/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs +++ b/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs | |||
@@ -32,7 +32,7 @@ using System.Text; | |||
32 | using System.Web; | 32 | using System.Web; |
33 | using OpenSim.Framework.Servers.HttpServer; | 33 | using OpenSim.Framework.Servers.HttpServer; |
34 | 34 | ||
35 | namespace OpenSim.Tests.Common.Mock | 35 | namespace OpenSim.Tests.Common |
36 | { | 36 | { |
37 | public class TestOSHttpResponse : IOSHttpResponse | 37 | public class TestOSHttpResponse : IOSHttpResponse |
38 | { | 38 | { |
diff --git a/OpenSim/Tests/Common/Mock/TestScene.cs b/OpenSim/Tests/Common/Mock/TestScene.cs index 40e2adc..45acf91 100644 --- a/OpenSim/Tests/Common/Mock/TestScene.cs +++ b/OpenSim/Tests/Common/Mock/TestScene.cs | |||
@@ -36,7 +36,7 @@ using OpenSim.Region.Framework.Scenes; | |||
36 | using OpenSim.Region.Physics.Manager; | 36 | using OpenSim.Region.Physics.Manager; |
37 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
38 | 38 | ||
39 | namespace OpenSim.Tests.Common.Mock | 39 | namespace OpenSim.Tests.Common |
40 | { | 40 | { |
41 | public class TestScene : Scene | 41 | public class TestScene : Scene |
42 | { | 42 | { |
diff --git a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs index 2be5524..be3a0cb 100644 --- a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs | |||
@@ -35,7 +35,7 @@ using OpenSim.Framework; | |||
35 | using OpenSim.Data; | 35 | using OpenSim.Data; |
36 | using OpenSim.Data.Null; | 36 | using OpenSim.Data.Null; |
37 | 37 | ||
38 | namespace OpenSim.Tests.Common.Mock | 38 | namespace OpenSim.Tests.Common |
39 | { | 39 | { |
40 | public class TestXInventoryDataPlugin : NullGenericDataHandler, IXInventoryData | 40 | public class TestXInventoryDataPlugin : NullGenericDataHandler, IXInventoryData |
41 | { | 41 | { |
diff --git a/OpenSim/Tests/Performance/NPCPerformanceTests.cs b/OpenSim/Tests/Performance/NPCPerformanceTests.cs index eb09061..e222dc2 100644 --- a/OpenSim/Tests/Performance/NPCPerformanceTests.cs +++ b/OpenSim/Tests/Performance/NPCPerformanceTests.cs | |||
@@ -45,7 +45,6 @@ using OpenSim.Region.Framework.Scenes; | |||
45 | using OpenSim.Region.OptionalModules.World.NPC; | 45 | using OpenSim.Region.OptionalModules.World.NPC; |
46 | using OpenSim.Services.AvatarService; | 46 | using OpenSim.Services.AvatarService; |
47 | using OpenSim.Tests.Common; | 47 | using OpenSim.Tests.Common; |
48 | using OpenSim.Tests.Common.Mock; | ||
49 | 48 | ||
50 | namespace OpenSim.Tests.Performance | 49 | namespace OpenSim.Tests.Performance |
51 | { | 50 | { |
diff --git a/OpenSim/Tests/Performance/ObjectPerformanceTests.cs b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs index 656a971..9dad423 100644 --- a/OpenSim/Tests/Performance/ObjectPerformanceTests.cs +++ b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs | |||
@@ -34,7 +34,6 @@ using OpenMetaverse; | |||
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Tests.Common; | 36 | using OpenSim.Tests.Common; |
37 | using OpenSim.Tests.Common.Mock; | ||
38 | 37 | ||
39 | namespace OpenSim.Tests.Performance | 38 | namespace OpenSim.Tests.Performance |
40 | { | 39 | { |
diff --git a/OpenSim/Tests/Performance/ScriptPerformanceTests.cs b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs index 4064edc..028f4b0 100644 --- a/OpenSim/Tests/Performance/ScriptPerformanceTests.cs +++ b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs | |||
@@ -40,7 +40,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Region.ScriptEngine.XEngine; | 41 | using OpenSim.Region.ScriptEngine.XEngine; |
42 | using OpenSim.Tests.Common; | 42 | using OpenSim.Tests.Common; |
43 | using OpenSim.Tests.Common.Mock; | ||
44 | 43 | ||
45 | namespace OpenSim.Tests.Performance | 44 | namespace OpenSim.Tests.Performance |
46 | { | 45 | { |
diff --git a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs index 1f220c0..0ab407e 100644 --- a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs +++ b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs | |||
@@ -41,7 +41,6 @@ using OpenSim.Region.CoreModules.Scripting.VectorRender; | |||
41 | using OpenSim.Region.Framework.Scenes; | 41 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenSim.Region.Framework.Scenes.Serialization; | 42 | using OpenSim.Region.Framework.Scenes.Serialization; |
43 | using OpenSim.Tests.Common; | 43 | using OpenSim.Tests.Common; |
44 | using OpenSim.Tests.Common.Mock; | ||
45 | 44 | ||
46 | namespace OpenSim.Tests.Stress | 45 | namespace OpenSim.Tests.Stress |
47 | { | 46 | { |
@@ -79,7 +78,7 @@ namespace OpenSim.Tests.Stress | |||
79 | Drawer d = new Drawer(this, i); | 78 | Drawer d = new Drawer(this, i); |
80 | drawers.Add(d); | 79 | drawers.Add(d); |
81 | Console.WriteLine("Starting drawer {0}", i); | 80 | Console.WriteLine("Starting drawer {0}", i); |
82 | Util.FireAndForget(o => d.Draw()); | 81 | Util.FireAndForget(o => d.Draw(), null, "VectorRenderModuleStressTests.TestConcurrentRepeatedDraw"); |
83 | } | 82 | } |
84 | 83 | ||
85 | Thread.Sleep(10 * 60 * 1000); | 84 | Thread.Sleep(10 * 60 * 1000); |
diff --git a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs index 4a7237c..0d43781 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs | |||
@@ -46,7 +46,10 @@ namespace pCampBot | |||
46 | 46 | ||
47 | public override void Action() | 47 | public override void Action() |
48 | { | 48 | { |
49 | Bot.Client.Self.Jump(false); | ||
50 | Bot.Client.Self.Movement.Stop = true; | ||
49 | m_interruptEvent.WaitOne(); | 51 | m_interruptEvent.WaitOne(); |
52 | Bot.Client.Self.Movement.Stop = false; | ||
50 | } | 53 | } |
51 | 54 | ||
52 | public override void Interrupt() | 55 | public override void Interrupt() |