aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs154
1 files changed, 97 insertions, 57 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 5005ac9..7c3875d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -61,6 +61,7 @@ namespace OpenSim.Region.Framework.Scenes
61 Time = 0, 61 Time = 0,
62 Distance = 1, 62 Distance = 1,
63 SimpleAngularDistance = 2, 63 SimpleAngularDistance = 2,
64 FrontBack = 3,
64 } 65 }
65 66
66 public delegate void SynchronizeSceneHandler(Scene scene); 67 public delegate void SynchronizeSceneHandler(Scene scene);
@@ -81,8 +82,6 @@ namespace OpenSim.Region.Framework.Scenes
81 82
82 protected Timer m_restartWaitTimer = new Timer(); 83 protected Timer m_restartWaitTimer = new Timer();
83 84
84 protected Thread m_updateEntitiesThread;
85
86 public SimStatsReporter StatsReporter; 85 public SimStatsReporter StatsReporter;
87 86
88 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 87 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
@@ -107,11 +106,11 @@ namespace OpenSim.Region.Framework.Scenes
107 public bool m_physicalPrim; 106 public bool m_physicalPrim;
108 public float m_maxNonphys = 256; 107 public float m_maxNonphys = 256;
109 public float m_maxPhys = 10; 108 public float m_maxPhys = 10;
110 public bool m_clampPrimSize = false; 109 public bool m_clampPrimSize;
111 public bool m_trustBinaries = false; 110 public bool m_trustBinaries;
112 public bool m_allowScriptCrossings = false; 111 public bool m_allowScriptCrossings;
113 public bool m_useFlySlow = false; 112 public bool m_useFlySlow;
114 public bool m_usePreJump = false; 113 public bool m_usePreJump;
115 public bool m_seeIntoRegionFromNeighbor; 114 public bool m_seeIntoRegionFromNeighbor;
116 // TODO: need to figure out how allow client agents but deny 115 // TODO: need to figure out how allow client agents but deny
117 // root agents when ACL denies access to root agent 116 // root agents when ACL denies access to root agent
@@ -119,11 +118,11 @@ namespace OpenSim.Region.Framework.Scenes
119 public int MaxUndoCount = 5; 118 public int MaxUndoCount = 5;
120 private int m_RestartTimerCounter; 119 private int m_RestartTimerCounter;
121 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing 120 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
122 private int m_incrementsof15seconds = 0; 121 private int m_incrementsof15seconds;
123 private volatile bool m_backingup = false; 122 private volatile bool m_backingup;
123 private bool m_useAsyncWhenPossible;
124 124
125 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); 125 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
126
127 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); 126 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
128 127
129 protected string m_simulatorVersion = "OpenSimulator Server"; 128 protected string m_simulatorVersion = "OpenSimulator Server";
@@ -143,8 +142,8 @@ namespace OpenSim.Region.Framework.Scenes
143 142
144 public IXfer XferManager; 143 public IXfer XferManager;
145 144
146 protected IAssetService m_AssetService = null; 145 protected IAssetService m_AssetService;
147 protected IAuthorizationService m_AuthorizationService = null; 146 protected IAuthorizationService m_AuthorizationService;
148 147
149 private Object m_heartbeatLock = new Object(); 148 private Object m_heartbeatLock = new Object();
150 149
@@ -185,7 +184,7 @@ namespace OpenSim.Region.Framework.Scenes
185 } 184 }
186 } 185 }
187 186
188 protected IInventoryService m_InventoryService = null; 187 protected IInventoryService m_InventoryService;
189 188
190 public IInventoryService InventoryService 189 public IInventoryService InventoryService
191 { 190 {
@@ -205,7 +204,7 @@ namespace OpenSim.Region.Framework.Scenes
205 } 204 }
206 } 205 }
207 206
208 protected IGridService m_GridService = null; 207 protected IGridService m_GridService;
209 208
210 public IGridService GridService 209 public IGridService GridService
211 { 210 {
@@ -253,9 +252,9 @@ namespace OpenSim.Region.Framework.Scenes
253 // Central Update Loop 252 // Central Update Loop
254 253
255 protected int m_fps = 10; 254 protected int m_fps = 10;
256 protected int m_frame = 0; 255 protected int m_frame;
257 protected float m_timespan = 0.089f; 256 protected float m_timespan = 0.089f;
258 protected DateTime m_lastupdate = DateTime.Now; 257 protected DateTime m_lastupdate = DateTime.UtcNow;
259 258
260 private int m_update_physics = 1; 259 private int m_update_physics = 1;
261 private int m_update_entitymovement = 1; 260 private int m_update_entitymovement = 1;
@@ -266,26 +265,26 @@ namespace OpenSim.Region.Framework.Scenes
266 private int m_update_terrain = 50; 265 private int m_update_terrain = 50;
267 private int m_update_land = 1; 266 private int m_update_land = 1;
268 267
269 private int frameMS = 0; 268 private int frameMS;
270 private int physicsMS2 = 0; 269 private int physicsMS2;
271 private int physicsMS = 0; 270 private int physicsMS;
272 private int otherMS = 0; 271 private int otherMS;
273 272
274 private bool m_physics_enabled = true; 273 private bool m_physics_enabled = true;
275 private bool m_scripts_enabled = true; 274 private bool m_scripts_enabled = true;
276 private string m_defaultScriptEngine; 275 private string m_defaultScriptEngine;
277 private int m_LastLogin = 0; 276 private int m_LastLogin;
278 private Thread HeartbeatThread = null; 277 private Thread HeartbeatThread;
279 private volatile bool shuttingdown = false; 278 private volatile bool shuttingdown;
280 279
281 private int m_lastUpdate = Environment.TickCount; 280 private int m_lastUpdate = Environment.TickCount;
282 private bool m_firstHeartbeat = true; 281 private bool m_firstHeartbeat = true;
283 282
284 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 283 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
285 private bool m_reprioritization_enabled = true; 284 private bool m_reprioritization_enabled = true;
286 private double m_reprioritization_interval = 2000.0; 285 private double m_reprioritization_interval = 5000.0;
287 private double m_root_reprioritization_distance = 5.0; 286 private double m_root_reprioritization_distance = 10.0;
288 private double m_child_reprioritization_distance = 10.0; 287 private double m_child_reprioritization_distance = 20.0;
289 288
290 private object m_deleting_scene_object = new object(); 289 private object m_deleting_scene_object = new object();
291 290
@@ -480,6 +479,9 @@ namespace OpenSim.Region.Framework.Scenes
480 // 479 //
481 IConfig startupConfig = m_config.Configs["Startup"]; 480 IConfig startupConfig = m_config.Configs["Startup"];
482 481
482 // Should we try to run loops synchronously or asynchronously?
483 m_useAsyncWhenPossible = startupConfig.GetBoolean("use_async_when_possible", false);
484
483 //Animation states 485 //Animation states
484 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 486 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
485 // TODO: Change default to true once the feature is supported 487 // TODO: Change default to true once the feature is supported
@@ -542,6 +544,9 @@ namespace OpenSim.Region.Framework.Scenes
542 case "simpleangulardistance": 544 case "simpleangulardistance":
543 m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; 545 m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
544 break; 546 break;
547 case "frontback":
548 m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack;
549 break;
545 default: 550 default:
546 m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); 551 m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
547 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 552 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
@@ -889,6 +894,9 @@ namespace OpenSim.Region.Framework.Scenes
889 { 894 {
890 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 895 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
891 896
897 m_restartTimer.Stop();
898 m_restartTimer.Close();
899
892 // Kick all ROOT agents with the message, 'The simulator is going down' 900 // Kick all ROOT agents with the message, 'The simulator is going down'
893 ForEachScenePresence(delegate(ScenePresence avatar) 901 ForEachScenePresence(delegate(ScenePresence avatar)
894 { 902 {
@@ -945,11 +953,8 @@ namespace OpenSim.Region.Framework.Scenes
945 HeartbeatThread = null; 953 HeartbeatThread = null;
946 } 954 }
947 m_lastUpdate = Environment.TickCount; 955 m_lastUpdate = Environment.TickCount;
948 HeartbeatThread = new Thread(new ParameterizedThreadStart(Heartbeat)); 956
949 HeartbeatThread.SetApartmentState(ApartmentState.MTA); 957 HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false);
950 HeartbeatThread.Name = string.Format("Heartbeat for region {0}", RegionInfo.RegionName);
951 HeartbeatThread.Priority = ThreadPriority.AboveNormal;
952 HeartbeatThread.Start();
953 } 958 }
954 959
955 /// <summary> 960 /// <summary>
@@ -976,12 +981,13 @@ namespace OpenSim.Region.Framework.Scenes
976 /// <summary> 981 /// <summary>
977 /// Performs per-frame updates regularly 982 /// Performs per-frame updates regularly
978 /// </summary> 983 /// </summary>
979 /// <param name="sender"></param> 984 private void Heartbeat()
980 /// <param name="e"></param>
981 private void Heartbeat(object sender)
982 { 985 {
983 if (!Monitor.TryEnter(m_heartbeatLock)) 986 if (!Monitor.TryEnter(m_heartbeatLock))
987 {
988 Watchdog.RemoveThread();
984 return; 989 return;
990 }
985 991
986 try 992 try
987 { 993 {
@@ -998,6 +1004,8 @@ namespace OpenSim.Region.Framework.Scenes
998 Monitor.Pulse(m_heartbeatLock); 1004 Monitor.Pulse(m_heartbeatLock);
999 Monitor.Exit(m_heartbeatLock); 1005 Monitor.Exit(m_heartbeatLock);
1000 } 1006 }
1007
1008 Watchdog.RemoveThread();
1001 } 1009 }
1002 1010
1003 /// <summary> 1011 /// <summary>
@@ -1016,10 +1024,11 @@ namespace OpenSim.Region.Framework.Scenes
1016//#endif 1024//#endif
1017 maintc = Environment.TickCount; 1025 maintc = Environment.TickCount;
1018 1026
1019 TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate; 1027 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1020 float physicsFPS = 0; 1028 float physicsFPS = 0;
1021 1029
1022 frameMS = Environment.TickCount; 1030 frameMS = Environment.TickCount;
1031
1023 try 1032 try
1024 { 1033 {
1025 // Increment the frame counter 1034 // Increment the frame counter
@@ -1101,6 +1110,11 @@ namespace OpenSim.Region.Framework.Scenes
1101 } 1110 }
1102 if (loginsdisabled && (m_frame > 20)) 1111 if (loginsdisabled && (m_frame > 20))
1103 { 1112 {
1113 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1114 // this is a rare case where we know we have just went through a long cycle of heap
1115 // allocations, and there is no more work to be done until someone logs in
1116 GC.Collect();
1117
1104 m_log.Debug("[REGION]: Enabling Logins"); 1118 m_log.Debug("[REGION]: Enabling Logins");
1105 loginsdisabled = false; 1119 loginsdisabled = false;
1106 } 1120 }
@@ -1139,13 +1153,16 @@ namespace OpenSim.Region.Framework.Scenes
1139 } 1153 }
1140 m_timedilation = tmpval; 1154 m_timedilation = tmpval;
1141 1155
1142 m_lastupdate = DateTime.Now; 1156 m_lastupdate = DateTime.UtcNow;
1143 } 1157 }
1144 maintc = Environment.TickCount - maintc; 1158 maintc = Environment.TickCount - maintc;
1145 maintc = (int)(m_timespan * 1000) - maintc; 1159 maintc = (int)(m_timespan * 1000) - maintc;
1146 1160
1147 if ((maintc < (m_timespan * 1000)) && maintc > 0) 1161 if ((maintc < (m_timespan * 1000)) && maintc > 0)
1148 Thread.Sleep(maintc); 1162 Thread.Sleep(maintc);
1163
1164 // Tell the watchdog that this thread is still alive
1165 Watchdog.UpdateThread();
1149 } 1166 }
1150 } 1167 }
1151 1168
@@ -1219,10 +1236,7 @@ namespace OpenSim.Region.Framework.Scenes
1219 if (!m_backingup) 1236 if (!m_backingup)
1220 { 1237 {
1221 m_backingup = true; 1238 m_backingup = true;
1222 1239 Util.FireAndForget(BackupWaitCallback);
1223 System.ComponentModel.BackgroundWorker backupWorker = new System.ComponentModel.BackgroundWorker();
1224 backupWorker.DoWork += delegate(object sender, System.ComponentModel.DoWorkEventArgs e) { Backup(); };
1225 backupWorker.RunWorkerAsync();
1226 } 1240 }
1227 } 1241 }
1228 1242
@@ -1235,6 +1249,14 @@ namespace OpenSim.Region.Framework.Scenes
1235 } 1249 }
1236 1250
1237 /// <summary> 1251 /// <summary>
1252 /// Wrapper for Backup() that can be called with Util.FireAndForget()
1253 /// </summary>
1254 private void BackupWaitCallback(object o)
1255 {
1256 Backup();
1257 }
1258
1259 /// <summary>
1238 /// Backup the scene. This acts as the main method of the backup thread. 1260 /// Backup the scene. This acts as the main method of the backup thread.
1239 /// </summary> 1261 /// </summary>
1240 /// <returns></returns> 1262 /// <returns></returns>
@@ -2460,7 +2482,7 @@ namespace OpenSim.Region.Framework.Scenes
2460 /// <param name="client"></param> 2482 /// <param name="client"></param>
2461 public override void AddNewClient(IClientAPI client) 2483 public override void AddNewClient(IClientAPI client)
2462 { 2484 {
2463 ClientManager.Add(client); 2485 m_clientManager.Add(client);
2464 2486
2465 CheckHeartbeat(); 2487 CheckHeartbeat();
2466 SubscribeToClientEvents(client); 2488 SubscribeToClientEvents(client);
@@ -3099,7 +3121,7 @@ namespace OpenSim.Region.Framework.Scenes
3099 3121
3100 // Remove the avatar from the scene 3122 // Remove the avatar from the scene
3101 m_sceneGraph.RemoveScenePresence(agentID); 3123 m_sceneGraph.RemoveScenePresence(agentID);
3102 ClientManager.Remove(agentID); 3124 m_clientManager.Remove(agentID);
3103 3125
3104 try 3126 try
3105 { 3127 {
@@ -3496,9 +3518,7 @@ namespace OpenSim.Region.Framework.Scenes
3496 public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying) 3518 public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
3497 { 3519 {
3498 ScenePresence presence; 3520 ScenePresence presence;
3499 3521 m_sceneGraph.TryGetAvatar(agentID, out presence);
3500 lock (m_sceneGraph.ScenePresences)
3501 m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence);
3502 3522
3503 if (presence != null) 3523 if (presence != null)
3504 { 3524 {
@@ -3709,8 +3729,7 @@ namespace OpenSim.Region.Framework.Scenes
3709 Vector3 lookAt, uint teleportFlags) 3729 Vector3 lookAt, uint teleportFlags)
3710 { 3730 {
3711 ScenePresence sp; 3731 ScenePresence sp;
3712 lock (m_sceneGraph.ScenePresences) 3732 m_sceneGraph.TryGetAvatar(remoteClient.AgentId, out sp);
3713 m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp);
3714 3733
3715 if (sp != null) 3734 if (sp != null)
3716 { 3735 {
@@ -4112,7 +4131,7 @@ namespace OpenSim.Region.Framework.Scenes
4112 /// This list is a new object, so it can be iterated over without locking. 4131 /// This list is a new object, so it can be iterated over without locking.
4113 /// </summary> 4132 /// </summary>
4114 /// <returns></returns> 4133 /// <returns></returns>
4115 public List<ScenePresence> GetScenePresences() 4134 public ScenePresence[] GetScenePresences()
4116 { 4135 {
4117 return m_sceneGraph.GetScenePresences(); 4136 return m_sceneGraph.GetScenePresences();
4118 } 4137 }
@@ -4159,15 +4178,13 @@ namespace OpenSim.Region.Framework.Scenes
4159 public void ForEachScenePresence(Action<ScenePresence> action) 4178 public void ForEachScenePresence(Action<ScenePresence> action)
4160 { 4179 {
4161 // We don't want to try to send messages if there are no avatars. 4180 // We don't want to try to send messages if there are no avatars.
4162 if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null) 4181 if (m_sceneGraph != null)
4163 { 4182 {
4164 try 4183 try
4165 { 4184 {
4166 List<ScenePresence> presenceList = GetScenePresences(); 4185 ScenePresence[] presences = GetScenePresences();
4167 foreach (ScenePresence presence in presenceList) 4186 for (int i = 0; i < presences.Length; i++)
4168 { 4187 action(presences[i]);
4169 action(presence);
4170 }
4171 } 4188 }
4172 catch (Exception e) 4189 catch (Exception e)
4173 { 4190 {
@@ -4239,7 +4256,30 @@ namespace OpenSim.Region.Framework.Scenes
4239 4256
4240 public void ForEachClient(Action<IClientAPI> action) 4257 public void ForEachClient(Action<IClientAPI> action)
4241 { 4258 {
4242 ClientManager.ForEach(action); 4259 ForEachClient(action, m_useAsyncWhenPossible);
4260 }
4261
4262 public void ForEachClient(Action<IClientAPI> action, bool doAsynchronous)
4263 {
4264 // FIXME: Asynchronous iteration is disabled until we have a threading model that
4265 // can support calling this function from an async packet handler without
4266 // potentially deadlocking
4267 m_clientManager.ForEachSync(action);
4268
4269 //if (doAsynchronous)
4270 // m_clientManager.ForEach(action);
4271 //else
4272 // m_clientManager.ForEachSync(action);
4273 }
4274
4275 public bool TryGetClient(UUID avatarID, out IClientAPI client)
4276 {
4277 return m_clientManager.TryGetValue(avatarID, out client);
4278 }
4279
4280 public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client)
4281 {
4282 return m_clientManager.TryGetValue(remoteEndPoint, out client);
4243 } 4283 }
4244 4284
4245 public void ForEachSOG(Action<SceneObjectGroup> action) 4285 public void ForEachSOG(Action<SceneObjectGroup> action)
@@ -4571,7 +4611,7 @@ namespace OpenSim.Region.Framework.Scenes
4571 { 4611 {
4572 case PhysicsJointType.Ball: 4612 case PhysicsJointType.Ball:
4573 { 4613 {
4574 PhysicsVector jointAnchor = PhysicsScene.GetJointAnchor(joint); 4614 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
4575 Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z); 4615 Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z);
4576 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update 4616 jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
4577 } 4617 }
@@ -4579,7 +4619,7 @@ namespace OpenSim.Region.Framework.Scenes
4579 4619
4580 case PhysicsJointType.Hinge: 4620 case PhysicsJointType.Hinge:
4581 { 4621 {
4582 PhysicsVector jointAnchor = PhysicsScene.GetJointAnchor(joint); 4622 Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
4583 4623
4584 // Normally, we would just ask the physics scene to return the axis for the joint. 4624 // Normally, we would just ask the physics scene to return the axis for the joint.
4585 // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should 4625 // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should