diff options
-rw-r--r--[-rwxr-xr-x] | OpenSim/Framework/MinHeap.cs | 27 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 30 | ||||
-rw-r--r-- | OpenSim/Region/Application/OpenSim.cs | 7 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs | 8 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 12 | ||||
-rw-r--r-- | ThirdParty/SmartThreadPool/SmartThreadPool.cs | 6 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 27 |
8 files changed, 83 insertions, 36 deletions
diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs index ad39bbc..33d0364 100755..100644 --- a/OpenSim/Framework/MinHeap.cs +++ b/OpenSim/Framework/MinHeap.cs | |||
@@ -1,3 +1,30 @@ | |||
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 | |||
1 | using System; | 28 | using System; |
2 | using System.Threading; | 29 | using System.Threading; |
3 | using System.Collections; | 30 | using System.Collections; |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index d09bd6d..a18a827 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -69,8 +69,6 @@ namespace OpenSim.Framework | |||
69 | /// </summary> | 69 | /// </summary> |
70 | public class Util | 70 | public class Util |
71 | { | 71 | { |
72 | private static SmartThreadPool m_ThreadPool = null; | ||
73 | |||
74 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 72 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
75 | 73 | ||
76 | private static uint nextXferID = 5000; | 74 | private static uint nextXferID = 5000; |
@@ -79,6 +77,9 @@ namespace OpenSim.Framework | |||
79 | private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; | 77 | private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; |
80 | private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; | 78 | private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; |
81 | private static object XferLock = new object(); | 79 | private static object XferLock = new object(); |
80 | /// <summary>Thread pool used for Util.FireAndForget if | ||
81 | /// FireAndForgetMethod.SmartThreadPool is used</summary> | ||
82 | private static SmartThreadPool m_ThreadPool; | ||
82 | 83 | ||
83 | // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. | 84 | // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. |
84 | private static readonly DateTime unixEpoch = | 85 | private static readonly DateTime unixEpoch = |
@@ -1319,21 +1320,14 @@ namespace OpenSim.Framework | |||
1319 | FireAndForget(callback, null); | 1320 | FireAndForget(callback, null); |
1320 | } | 1321 | } |
1321 | 1322 | ||
1322 | public static void SetMaxThreads(int maxThreads) | 1323 | public static void InitThreadPool(int maxThreads) |
1323 | { | 1324 | { |
1325 | if (maxThreads < 2) | ||
1326 | throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2"); | ||
1324 | if (m_ThreadPool != null) | 1327 | if (m_ThreadPool != null) |
1325 | return; | 1328 | throw new InvalidOperationException("SmartThreadPool is already initialized"); |
1326 | |||
1327 | STPStartInfo startInfo = new STPStartInfo(); | ||
1328 | startInfo.IdleTimeout = 2000; // 2 seconds | ||
1329 | startInfo.MaxWorkerThreads = maxThreads; | ||
1330 | startInfo.MinWorkerThreads = 2; | ||
1331 | startInfo.StackSize = 524288; | ||
1332 | startInfo.ThreadPriority = ThreadPriority.Normal; | ||
1333 | |||
1334 | startInfo.StartSuspended = false; | ||
1335 | 1329 | ||
1336 | m_ThreadPool = new SmartThreadPool(startInfo); | 1330 | m_ThreadPool = new SmartThreadPool(2000, maxThreads, 2); |
1337 | } | 1331 | } |
1338 | 1332 | ||
1339 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj) | 1333 | public static void FireAndForget(System.Threading.WaitCallback callback, object obj) |
@@ -1341,20 +1335,22 @@ namespace OpenSim.Framework | |||
1341 | switch (FireAndForgetMethod) | 1335 | switch (FireAndForgetMethod) |
1342 | { | 1336 | { |
1343 | case FireAndForgetMethod.UnsafeQueueUserWorkItem: | 1337 | case FireAndForgetMethod.UnsafeQueueUserWorkItem: |
1344 | System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj); | 1338 | ThreadPool.UnsafeQueueUserWorkItem(callback, obj); |
1345 | break; | 1339 | break; |
1346 | case FireAndForgetMethod.QueueUserWorkItem: | 1340 | case FireAndForgetMethod.QueueUserWorkItem: |
1347 | System.Threading.ThreadPool.QueueUserWorkItem(callback, obj); | 1341 | ThreadPool.QueueUserWorkItem(callback, obj); |
1348 | break; | 1342 | break; |
1349 | case FireAndForgetMethod.BeginInvoke: | 1343 | case FireAndForgetMethod.BeginInvoke: |
1350 | FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>(); | 1344 | FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>(); |
1351 | wrapper.FireAndForget(callback, obj); | 1345 | wrapper.FireAndForget(callback, obj); |
1352 | break; | 1346 | break; |
1353 | case FireAndForgetMethod.SmartThreadPool: | 1347 | case FireAndForgetMethod.SmartThreadPool: |
1348 | if (m_ThreadPool != null) | ||
1349 | m_ThreadPool = new SmartThreadPool(2000, 15, 2); | ||
1354 | m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj); | 1350 | m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj); |
1355 | break; | 1351 | break; |
1356 | case FireAndForgetMethod.Thread: | 1352 | case FireAndForgetMethod.Thread: |
1357 | System.Threading.Thread thread = new System.Threading.Thread(delegate(object o) { callback(o); }); | 1353 | Thread thread = new Thread(delegate(object o) { callback(o); }); |
1358 | thread.Start(obj); | 1354 | thread.Start(obj); |
1359 | break; | 1355 | break; |
1360 | default: | 1356 | default: |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index c04b8c2..26298e7 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -67,7 +67,7 @@ namespace OpenSim | |||
67 | 67 | ||
68 | IConfig startupConfig = m_config.Source.Configs["Startup"]; | 68 | IConfig startupConfig = m_config.Source.Configs["Startup"]; |
69 | 69 | ||
70 | Util.SetMaxThreads(startupConfig.GetInt("MaxPoolThreads", 15)); | 70 | int stpMaxThreads = 15; |
71 | 71 | ||
72 | if (startupConfig != null) | 72 | if (startupConfig != null) |
73 | { | 73 | { |
@@ -100,8 +100,13 @@ namespace OpenSim | |||
100 | FireAndForgetMethod asyncCallMethod; | 100 | FireAndForgetMethod asyncCallMethod; |
101 | if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) | 101 | if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod)) |
102 | Util.FireAndForgetMethod = asyncCallMethod; | 102 | Util.FireAndForgetMethod = asyncCallMethod; |
103 | |||
104 | stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15); | ||
103 | } | 105 | } |
104 | 106 | ||
107 | if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) | ||
108 | Util.InitThreadPool(stpMaxThreads); | ||
109 | |||
105 | m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); | 110 | m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); |
106 | } | 111 | } |
107 | 112 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 0ba76ec..5acf25f 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -827,7 +827,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
827 | for (int i = x1; i <= x2; i++) | 827 | for (int i = x1; i <= x2; i++) |
828 | SendLayerData(i, y1, map); | 828 | SendLayerData(i, y1, map); |
829 | 829 | ||
830 | // Column | 830 | // Column |
831 | for (int j = y1 + 1; j <= y2; j++) | 831 | for (int j = y1 + 1; j <= y2; j++) |
832 | SendLayerData(x2, j, map); | 832 | SendLayerData(x2, j, map); |
833 | 833 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index ad05bab..f5ab454 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs | |||
@@ -274,8 +274,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
274 | } | 274 | } |
275 | m_RootAgents[agentID] = scene; | 275 | m_RootAgents[agentID] = scene; |
276 | } | 276 | } |
277 | |||
277 | // inform messaging server that agent changed the region | 278 | // inform messaging server that agent changed the region |
278 | NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); | 279 | Util.FireAndForget( |
280 | delegate(object o) | ||
281 | { | ||
282 | NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); | ||
283 | } | ||
284 | ); | ||
279 | } | 285 | } |
280 | 286 | ||
281 | private void OnEconomyDataRequest(UUID agentID) | 287 | private void OnEconomyDataRequest(UUID agentID) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 11f255f..669189d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -1267,12 +1267,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1267 | protected void SetScale(SceneObjectPart part, LSL_Vector scale) | 1267 | protected void SetScale(SceneObjectPart part, LSL_Vector scale) |
1268 | { | 1268 | { |
1269 | // TODO: this needs to trigger a persistance save as well | 1269 | // TODO: this needs to trigger a persistance save as well |
1270 | |||
1271 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 1270 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
1272 | return; | 1271 | return; |
1273 | 1272 | if (scale.x < 0.01) | |
1274 | if (scale.x < 0.01 || scale.y < 0.01 || scale.z < 0.01) | 1273 | scale.x = 0.01; |
1275 | return; | 1274 | if (scale.y < 0.01) |
1275 | scale.y = 0.01; | ||
1276 | if (scale.z < 0.01) | ||
1277 | scale.z = 0.01; | ||
1276 | 1278 | ||
1277 | if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical) | 1279 | if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical) |
1278 | { | 1280 | { |
@@ -1283,12 +1285,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1283 | if (scale.z > World.m_maxPhys) | 1285 | if (scale.z > World.m_maxPhys) |
1284 | scale.z = World.m_maxPhys; | 1286 | scale.z = World.m_maxPhys; |
1285 | } | 1287 | } |
1288 | |||
1286 | if (scale.x > World.m_maxNonphys) | 1289 | if (scale.x > World.m_maxNonphys) |
1287 | scale.x = World.m_maxNonphys; | 1290 | scale.x = World.m_maxNonphys; |
1288 | if (scale.y > World.m_maxNonphys) | 1291 | if (scale.y > World.m_maxNonphys) |
1289 | scale.y = World.m_maxNonphys; | 1292 | scale.y = World.m_maxNonphys; |
1290 | if (scale.z > World.m_maxNonphys) | 1293 | if (scale.z > World.m_maxNonphys) |
1291 | scale.z = World.m_maxNonphys; | 1294 | scale.z = World.m_maxNonphys; |
1295 | |||
1292 | Vector3 tmp = part.Scale; | 1296 | Vector3 tmp = part.Scale; |
1293 | tmp.X = (float)scale.x; | 1297 | tmp.X = (float)scale.x; |
1294 | tmp.Y = (float)scale.y; | 1298 | tmp.Y = (float)scale.y; |
diff --git a/ThirdParty/SmartThreadPool/SmartThreadPool.cs b/ThirdParty/SmartThreadPool/SmartThreadPool.cs index c21984e..bd52f62 100644 --- a/ThirdParty/SmartThreadPool/SmartThreadPool.cs +++ b/ThirdParty/SmartThreadPool/SmartThreadPool.cs | |||
@@ -499,7 +499,11 @@ namespace Amib.Threading | |||
499 | } | 499 | } |
500 | 500 | ||
501 | // Create a new thread | 501 | // Create a new thread |
502 | Thread workerThread = new Thread(new ThreadStart(ProcessQueuedItems), _stpStartInfo.StackSize); | 502 | Thread workerThread; |
503 | if (_stpStartInfo.StackSize > 0) | ||
504 | workerThread = new Thread(ProcessQueuedItems, _stpStartInfo.StackSize); | ||
505 | else | ||
506 | workerThread = new Thread(ProcessQueuedItems); | ||
503 | 507 | ||
504 | // Configure the new thread and start it | 508 | // Configure the new thread and start it |
505 | workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; | 509 | workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 79d57d2..6ff70fc 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -38,8 +38,15 @@ | |||
38 | 38 | ||
39 | ; Sets the method that OpenSim will use to fire asynchronous | 39 | ; Sets the method that OpenSim will use to fire asynchronous |
40 | ; events. Valid values are UnsafeQueueUserWorkItem, | 40 | ; events. Valid values are UnsafeQueueUserWorkItem, |
41 | ; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread | 41 | ; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread. |
42 | ; async_call_method = SmartThreadPool | 42 | ; SmartThreadPool is reported to work well on Mono/Linux, but |
43 | ; UnsafeQueueUserWorkItem has been benchmarked with better | ||
44 | ; performance on .NET/Windows | ||
45 | ;async_call_method = SmartThreadPool | ||
46 | |||
47 | ; Max threads to allocate on the FireAndForget thread pool | ||
48 | ; when running with the SmartThreadPool option above | ||
49 | MaxPoolThreads = 15 | ||
43 | 50 | ||
44 | ; ## | 51 | ; ## |
45 | ; ## CLIENTS | 52 | ; ## CLIENTS |
@@ -51,9 +58,6 @@ | |||
51 | ; Set this to the DLL containing the client stack to use. | 58 | ; Set this to the DLL containing the client stack to use. |
52 | clientstack_plugin="OpenSim.Region.ClientStack.LindenUDP.dll" | 59 | clientstack_plugin="OpenSim.Region.ClientStack.LindenUDP.dll" |
53 | 60 | ||
54 | ; Max threads to allocate on the FireAndForget pool | ||
55 | MaxPoolThreads = 15 | ||
56 | |||
57 | ; ## | 61 | ; ## |
58 | ; ## REGIONS | 62 | ; ## REGIONS |
59 | ; ## | 63 | ; ## |
@@ -1392,12 +1396,13 @@ | |||
1392 | ;TextureDataLimit = 5 | 1396 | ;TextureDataLimit = 5 |
1393 | 1397 | ||
1394 | [InterestManagement] | 1398 | [InterestManagement] |
1395 | ; This section controls how state updates are prioritized for each client | 1399 | ; This section controls how state updates are prioritized for each client |
1396 | UpdatePrioritizationScheme = Distance | 1400 | ; Valid values are Time, Distance, and SimpleAngularDistance |
1397 | ReprioritizeUpdate = true | 1401 | UpdatePrioritizationScheme = Distance; |
1398 | RootUpdateReprioritizationDistance = 10.0 | 1402 | ReprioritizationEnabled = true; |
1399 | ChildUpdateReprioritizationDistance = 20.0 | 1403 | ReprioritizationInterval = 2000.0; |
1400 | ReprioritizeUpdatesInterval = 5000.0 | 1404 | RootReprioritizationDistance = 10.0; |
1405 | ChildReprioritizationDistance = 20.0; | ||
1401 | 1406 | ||
1402 | ;; | 1407 | ;; |
1403 | ;; These are defaults that are overwritten below in [Architecture]. | 1408 | ;; These are defaults that are overwritten below in [Architecture]. |