diff options
author | John Hurliman | 2009-10-26 16:33:04 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-26 16:33:04 -0700 |
commit | 4847e62e9fd1cd473cc180220a379efba93f94a6 (patch) | |
tree | 509da282d16f1cfa7d2500debc5b56c48799ec98 | |
parent | Added calls to GC.AddMemoryPressure() when unmanaged memory is allocated for ... (diff) | |
download | opensim-SC_OLD-4847e62e9fd1cd473cc180220a379efba93f94a6.zip opensim-SC_OLD-4847e62e9fd1cd473cc180220a379efba93f94a6.tar.gz opensim-SC_OLD-4847e62e9fd1cd473cc180220a379efba93f94a6.tar.bz2 opensim-SC_OLD-4847e62e9fd1cd473cc180220a379efba93f94a6.tar.xz |
* Switched all operations on the list of clients that could be either sync or async to use Scene.ForEachClient() instead of referencing ClientManager directly
* Added a new [Startup] config option called use_async_when_possible to signal how to run operations that could be either sync or async
* Changed Scene.ForEachClient to respect use_async_when_possible
* Fixing a potential deadlock in Parallel.ForEach by locking on a temporary object instead of the enumerator (which may be shared across multiple invocations on ForEach). Thank you diva
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Parallel.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 48 | ||||
-rw-r--r-- | OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs | 6 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 7 |
7 files changed, 44 insertions, 28 deletions
diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs index 70eecdc..515852f 100644 --- a/OpenSim/Framework/Parallel.cs +++ b/OpenSim/Framework/Parallel.cs | |||
@@ -118,6 +118,7 @@ namespace OpenSim.Framework | |||
118 | int counter = threadCount; | 118 | int counter = threadCount; |
119 | AutoResetEvent threadFinishEvent = new AutoResetEvent(false); | 119 | AutoResetEvent threadFinishEvent = new AutoResetEvent(false); |
120 | IEnumerator<T> enumerator = enumerable.GetEnumerator(); | 120 | IEnumerator<T> enumerator = enumerable.GetEnumerator(); |
121 | object syncRoot = new object(); | ||
121 | Exception exception = null; | 122 | Exception exception = null; |
122 | 123 | ||
123 | for (int i = 0; i < threadCount; i++) | 124 | for (int i = 0; i < threadCount; i++) |
@@ -131,7 +132,7 @@ namespace OpenSim.Framework | |||
131 | { | 132 | { |
132 | T entry; | 133 | T entry; |
133 | 134 | ||
134 | lock (enumerator) | 135 | lock (syncRoot) |
135 | { | 136 | { |
136 | if (!enumerator.MoveNext()) | 137 | if (!enumerator.MoveNext()) |
137 | break; | 138 | break; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 8c3c5be..dee0a39 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -262,7 +262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
262 | for (int i = 0; i < packetCount; i++) | 262 | for (int i = 0; i < packetCount; i++) |
263 | { | 263 | { |
264 | byte[] data = datas[i]; | 264 | byte[] data = datas[i]; |
265 | m_scene.ClientManager.ForEach( | 265 | m_scene.ForEachClient( |
266 | delegate(IClientAPI client) | 266 | delegate(IClientAPI client) |
267 | { | 267 | { |
268 | if (client is LLClientView) | 268 | if (client is LLClientView) |
@@ -274,7 +274,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
274 | else | 274 | else |
275 | { | 275 | { |
276 | byte[] data = packet.ToBytes(); | 276 | byte[] data = packet.ToBytes(); |
277 | m_scene.ClientManager.ForEach( | 277 | m_scene.ForEachClient( |
278 | delegate(IClientAPI client) | 278 | delegate(IClientAPI client) |
279 | { | 279 | { |
280 | if (client is LLClientView) | 280 | if (client is LLClientView) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 7855862..273c128 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | |||
@@ -114,7 +114,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
114 | { | 114 | { |
115 | string reasonStr = Utils.BytesToString(reason); | 115 | string reasonStr = Utils.BytesToString(reason); |
116 | 116 | ||
117 | m_scene.ClientManager.ForEach( | 117 | m_scene.ForEachClient( |
118 | delegate(IClientAPI controller) | 118 | delegate(IClientAPI controller) |
119 | { | 119 | { |
120 | if (controller.AgentId != godID) | 120 | if (controller.AgentId != godID) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index ac89f7b..cfe32d0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -408,7 +408,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
408 | } | 408 | } |
409 | ViewerEffectPacket.EffectBlock[] effectBlockArray = effectBlock.ToArray(); | 409 | ViewerEffectPacket.EffectBlock[] effectBlockArray = effectBlock.ToArray(); |
410 | 410 | ||
411 | ClientManager.ForEach( | 411 | ForEachClient( |
412 | delegate(IClientAPI client) | 412 | delegate(IClientAPI client) |
413 | { | 413 | { |
414 | if (client.AgentId != remoteClient.AgentId) | 414 | if (client.AgentId != remoteClient.AgentId) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4776bed..91367db 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -106,11 +106,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
106 | public bool m_physicalPrim; | 106 | public bool m_physicalPrim; |
107 | public float m_maxNonphys = 256; | 107 | public float m_maxNonphys = 256; |
108 | public float m_maxPhys = 10; | 108 | public float m_maxPhys = 10; |
109 | public bool m_clampPrimSize = false; | 109 | public bool m_clampPrimSize; |
110 | public bool m_trustBinaries = false; | 110 | public bool m_trustBinaries; |
111 | public bool m_allowScriptCrossings = false; | 111 | public bool m_allowScriptCrossings; |
112 | public bool m_useFlySlow = false; | 112 | public bool m_useFlySlow; |
113 | public bool m_usePreJump = false; | 113 | public bool m_usePreJump; |
114 | public bool m_seeIntoRegionFromNeighbor; | 114 | public bool m_seeIntoRegionFromNeighbor; |
115 | // TODO: need to figure out how allow client agents but deny | 115 | // TODO: need to figure out how allow client agents but deny |
116 | // root agents when ACL denies access to root agent | 116 | // root agents when ACL denies access to root agent |
@@ -118,11 +118,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
118 | public int MaxUndoCount = 5; | 118 | public int MaxUndoCount = 5; |
119 | private int m_RestartTimerCounter; | 119 | private int m_RestartTimerCounter; |
120 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing | 120 | private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing |
121 | private int m_incrementsof15seconds = 0; | 121 | private int m_incrementsof15seconds; |
122 | private volatile bool m_backingup = false; | 122 | private volatile bool m_backingup; |
123 | private bool m_useAsyncWhenPossible = true; | ||
123 | 124 | ||
124 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); | 125 | private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); |
125 | |||
126 | private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); | 126 | private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); |
127 | 127 | ||
128 | protected string m_simulatorVersion = "OpenSimulator Server"; | 128 | protected string m_simulatorVersion = "OpenSimulator Server"; |
@@ -142,8 +142,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
142 | 142 | ||
143 | public IXfer XferManager; | 143 | public IXfer XferManager; |
144 | 144 | ||
145 | protected IAssetService m_AssetService = null; | 145 | protected IAssetService m_AssetService; |
146 | protected IAuthorizationService m_AuthorizationService = null; | 146 | protected IAuthorizationService m_AuthorizationService; |
147 | 147 | ||
148 | private Object m_heartbeatLock = new Object(); | 148 | private Object m_heartbeatLock = new Object(); |
149 | 149 | ||
@@ -184,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | protected IInventoryService m_InventoryService = null; | 187 | protected IInventoryService m_InventoryService; |
188 | 188 | ||
189 | public IInventoryService InventoryService | 189 | public IInventoryService InventoryService |
190 | { | 190 | { |
@@ -204,7 +204,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
204 | } | 204 | } |
205 | } | 205 | } |
206 | 206 | ||
207 | protected IGridService m_GridService = null; | 207 | protected IGridService m_GridService; |
208 | 208 | ||
209 | public IGridService GridService | 209 | public IGridService GridService |
210 | { | 210 | { |
@@ -252,7 +252,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
252 | // Central Update Loop | 252 | // Central Update Loop |
253 | 253 | ||
254 | protected int m_fps = 10; | 254 | protected int m_fps = 10; |
255 | protected int m_frame = 0; | 255 | protected int m_frame; |
256 | protected float m_timespan = 0.089f; | 256 | protected float m_timespan = 0.089f; |
257 | protected DateTime m_lastupdate = DateTime.UtcNow; | 257 | protected DateTime m_lastupdate = DateTime.UtcNow; |
258 | 258 | ||
@@ -265,17 +265,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
265 | private int m_update_terrain = 50; | 265 | private int m_update_terrain = 50; |
266 | private int m_update_land = 1; | 266 | private int m_update_land = 1; |
267 | 267 | ||
268 | private int frameMS = 0; | 268 | private int frameMS; |
269 | private int physicsMS2 = 0; | 269 | private int physicsMS2; |
270 | private int physicsMS = 0; | 270 | private int physicsMS; |
271 | private int otherMS = 0; | 271 | private int otherMS; |
272 | 272 | ||
273 | private bool m_physics_enabled = true; | 273 | private bool m_physics_enabled = true; |
274 | private bool m_scripts_enabled = true; | 274 | private bool m_scripts_enabled = true; |
275 | private string m_defaultScriptEngine; | 275 | private string m_defaultScriptEngine; |
276 | private int m_LastLogin = 0; | 276 | private int m_LastLogin; |
277 | private Thread HeartbeatThread = null; | 277 | private Thread HeartbeatThread; |
278 | private volatile bool shuttingdown = false; | 278 | private volatile bool shuttingdown; |
279 | 279 | ||
280 | private int m_lastUpdate = Environment.TickCount; | 280 | private int m_lastUpdate = Environment.TickCount; |
281 | private bool m_firstHeartbeat = true; | 281 | private bool m_firstHeartbeat = true; |
@@ -479,6 +479,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
479 | // | 479 | // |
480 | IConfig startupConfig = m_config.Configs["Startup"]; | 480 | IConfig startupConfig = m_config.Configs["Startup"]; |
481 | 481 | ||
482 | // Should we try to run loops synchronously or asynchronously? | ||
483 | m_useAsyncWhenPossible = startupConfig.GetBoolean("use_async_when_possible", true); | ||
484 | |||
482 | //Animation states | 485 | //Animation states |
483 | m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); | 486 | m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); |
484 | // TODO: Change default to true once the feature is supported | 487 | // TODO: Change default to true once the feature is supported |
@@ -4253,7 +4256,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4253 | 4256 | ||
4254 | public void ForEachClient(Action<IClientAPI> action) | 4257 | public void ForEachClient(Action<IClientAPI> action) |
4255 | { | 4258 | { |
4256 | ClientManager.ForEachSync(action); | 4259 | if (m_useAsyncWhenPossible) |
4260 | ClientManager.ForEach(action); | ||
4261 | else | ||
4262 | ClientManager.ForEachSync(action); | ||
4257 | } | 4263 | } |
4258 | 4264 | ||
4259 | public void ForEachSOG(Action<SceneObjectGroup> action) | 4265 | public void ForEachSOG(Action<SceneObjectGroup> action) |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index b6513e2..1a72971 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs | |||
@@ -183,10 +183,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
183 | public virtual void HideFromAll() | 183 | public virtual void HideFromAll() |
184 | { | 184 | { |
185 | foreach (SceneObjectPart part in m_Entity.Children.Values) | 185 | foreach (SceneObjectPart part in m_Entity.Children.Values) |
186 | m_Entity.Scene.ClientManager.ForEach( | 186 | { |
187 | m_Entity.Scene.ForEachClient( | ||
187 | delegate(IClientAPI controller) | 188 | delegate(IClientAPI controller) |
188 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } | 189 | { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } |
189 | ); | 190 | ); |
191 | } | ||
190 | } | 192 | } |
191 | 193 | ||
192 | public void SendFullUpdate(IClientAPI client) | 194 | public void SendFullUpdate(IClientAPI client) |
@@ -202,7 +204,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
202 | 204 | ||
203 | public void SendFullUpdateToAll() | 205 | public void SendFullUpdateToAll() |
204 | { | 206 | { |
205 | m_Entity.Scene.ClientManager.ForEach( | 207 | m_Entity.Scene.ForEachClient( |
206 | delegate(IClientAPI controller) | 208 | delegate(IClientAPI controller) |
207 | { m_Entity.SendFullUpdateToClient(controller); } | 209 | { m_Entity.SendFullUpdateToClient(controller); } |
208 | ); | 210 | ); |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 9ee9829..2adc87f 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -44,6 +44,13 @@ | |||
44 | ; performance on .NET/Windows | 44 | ; performance on .NET/Windows |
45 | ;async_call_method = SmartThreadPool | 45 | ;async_call_method = SmartThreadPool |
46 | 46 | ||
47 | ; There are several operations on large collections (such as | ||
48 | ; the current avatar list) that can be run synchronously or | ||
49 | ; in parallel. Running in parallel should increase performance | ||
50 | ; on a multi-core system, but will make debugging more | ||
51 | ; difficult if something deadlocks or times out | ||
52 | use_async_when_possible = true | ||
53 | |||
47 | ; Max threads to allocate on the FireAndForget thread pool | 54 | ; Max threads to allocate on the FireAndForget thread pool |
48 | ; when running with the SmartThreadPool option above | 55 | ; when running with the SmartThreadPool option above |
49 | MaxPoolThreads = 15 | 56 | MaxPoolThreads = 15 |