aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs215
2 files changed, 147 insertions, 70 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index cded9be..f5623bd 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -125,7 +125,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
125 125
126 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations 126 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
127 // are referenced with lower case names! 127 // are referenced with lower case names!
128 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name); 128 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
129 if (animID == UUID.Zero) 129 if (animID == UUID.Zero)
130 return; 130 return;
131 131
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 44a738e..6e70c36 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -172,6 +172,11 @@ namespace OpenSim.Region.Framework.Scenes
172 } 172 }
173 173
174 /// <summary> 174 /// <summary>
175 /// Current maintenance run number
176 /// </summary>
177 public uint MaintenanceRun { get; private set; }
178
179 /// <summary>
175 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we 180 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
176 /// will sleep for the remaining period. 181 /// will sleep for the remaining period.
177 /// </summary> 182 /// </summary>
@@ -181,6 +186,11 @@ namespace OpenSim.Region.Framework.Scenes
181 /// </remarks> 186 /// </remarks>
182 public float MinFrameTime { get; private set; } 187 public float MinFrameTime { get; private set; }
183 188
189 /// <summary>
190 /// The minimum length of time in seconds that will be taken for a maintenance run.
191 /// </summary>
192 public float MinMaintenanceTime { get; private set; }
193
184 private int m_update_physics = 1; 194 private int m_update_physics = 1;
185 private int m_update_entitymovement = 1; 195 private int m_update_entitymovement = 1;
186 private int m_update_objects = 1; 196 private int m_update_objects = 1;
@@ -210,19 +220,22 @@ namespace OpenSim.Region.Framework.Scenes
210 220
211 public bool CombineRegions = false; 221 public bool CombineRegions = false;
212 /// <summary> 222 /// <summary>
223 /// Tick at which the last maintenance run occurred.
224 /// </summary>
225 private int m_lastMaintenanceTick;
226
227 /// <summary>
213 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 228 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
214 /// asynchronously from the update loop. 229 /// asynchronously from the update loop.
215 /// </summary> 230 /// </summary>
216 private bool m_cleaningTemps = false; 231 private bool m_cleaningTemps = false;
217 232
218 private Object m_heartbeatLock = new Object(); 233// private Object m_heartbeatLock = new Object();
219 234
220 // TODO: Possibly stop other classes being able to manipulate this directly. 235 // TODO: Possibly stop other classes being able to manipulate this directly.
221 private SceneGraph m_sceneGraph; 236 private SceneGraph m_sceneGraph;
222 private volatile int m_bordersLocked; 237 private volatile int m_bordersLocked;
223// private int m_RestartTimerCounter;
224 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing 238 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
225// private int m_incrementsof15seconds;
226 private volatile bool m_backingup; 239 private volatile bool m_backingup;
227 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); 240 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
228 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); 241 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
@@ -230,16 +243,34 @@ namespace OpenSim.Region.Framework.Scenes
230 private bool m_physics_enabled = true; 243 private bool m_physics_enabled = true;
231 private bool m_scripts_enabled = true; 244 private bool m_scripts_enabled = true;
232 private string m_defaultScriptEngine; 245 private string m_defaultScriptEngine;
246
247 /// <summary>
248 /// Tick at which the last login occurred.
249 /// </summary>
233 private int m_LastLogin; 250 private int m_LastLogin;
234 private Thread HeartbeatThread = null;
235 private volatile bool shuttingdown;
236 251
237 private int m_lastUpdate;
238 private int m_lastIncoming; 252 private int m_lastIncoming;
239 private int m_lastOutgoing; 253 private int m_lastOutgoing;
240 private bool m_firstHeartbeat = true;
241 private int m_hbRestarts = 0; 254 private int m_hbRestarts = 0;
242 255
256
257 /// <summary>
258 /// Thread that runs the scene loop.
259 /// </summary>
260 private Thread m_heartbeatThread;
261
262 /// <summary>
263 /// True if these scene is in the process of shutting down or is shutdown.
264 /// </summary>
265 public bool ShuttingDown
266 {
267 get { return m_shuttingDown; }
268 }
269 private volatile bool m_shuttingDown;
270
271// private int m_lastUpdate;
272 private bool m_firstHeartbeat = true;
273
243 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; 274 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
244 private bool m_reprioritizationEnabled = true; 275 private bool m_reprioritizationEnabled = true;
245 private double m_reprioritizationInterval = 5000.0; 276 private double m_reprioritizationInterval = 5000.0;
@@ -566,6 +597,7 @@ namespace OpenSim.Region.Framework.Scenes
566 { 597 {
567 m_config = config; 598 m_config = config;
568 MinFrameTime = 0.089f; 599 MinFrameTime = 0.089f;
600 MinMaintenanceTime = 1;
569 601
570 Random random = new Random(); 602 Random random = new Random();
571 603
@@ -577,7 +609,6 @@ namespace OpenSim.Region.Framework.Scenes
577 m_EstateDataService = estateDataService; 609 m_EstateDataService = estateDataService;
578 m_regionHandle = m_regInfo.RegionHandle; 610 m_regionHandle = m_regInfo.RegionHandle;
579 m_regionName = m_regInfo.RegionName; 611 m_regionName = m_regInfo.RegionName;
580 m_lastUpdate = Util.EnvironmentTickCount();
581 m_lastIncoming = 0; 612 m_lastIncoming = 0;
582 m_lastOutgoing = 0; 613 m_lastOutgoing = 0;
583 614
@@ -834,18 +865,13 @@ namespace OpenSim.Region.Framework.Scenes
834 865
835 m_permissions = new ScenePermissions(this); 866 m_permissions = new ScenePermissions(this);
836 867
837 m_lastUpdate = Util.EnvironmentTickCount(); 868// m_lastUpdate = Util.EnvironmentTickCount();
838 } 869 }
839 870
840 #endregion 871 #endregion
841 872
842 #region Startup / Close Methods 873 #region Startup / Close Methods
843 874
844 public bool ShuttingDown
845 {
846 get { return shuttingdown; }
847 }
848
849 /// <value> 875 /// <value>
850 /// The scene graph for this scene 876 /// The scene graph for this scene
851 /// </value> 877 /// </value>
@@ -1107,6 +1133,12 @@ namespace OpenSim.Region.Framework.Scenes
1107 m_physics_enabled = enablePhysics; 1133 m_physics_enabled = enablePhysics;
1108 } 1134 }
1109 1135
1136// if (options.ContainsKey("collisions"))
1137// {
1138// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow
1139// // the avatar themselves to collide with the ground.
1140// }
1141
1110 if (options.ContainsKey("teleport")) 1142 if (options.ContainsKey("teleport"))
1111 { 1143 {
1112 bool enableTeleportDebugging; 1144 bool enableTeleportDebugging;
@@ -1158,8 +1190,7 @@ namespace OpenSim.Region.Framework.Scenes
1158 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); 1190 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
1159 1191
1160 // Stop updating the scene objects and agents. 1192 // Stop updating the scene objects and agents.
1161 //m_heartbeatTimer.Close(); 1193 m_shuttingDown = true;
1162 shuttingdown = true;
1163 1194
1164 m_log.Debug("[SCENE]: Persisting changed objects"); 1195 m_log.Debug("[SCENE]: Persisting changed objects");
1165 EventManager.TriggerSceneShuttingDown(this); 1196 EventManager.TriggerSceneShuttingDown(this);
@@ -1183,16 +1214,16 @@ namespace OpenSim.Region.Framework.Scenes
1183 } 1214 }
1184 1215
1185 /// <summary> 1216 /// <summary>
1186 /// Start the timer which triggers regular scene updates 1217 /// Start the scene
1187 /// </summary> 1218 /// </summary>
1188 public void StartTimer() 1219 public void Start()
1189 { 1220 {
1190// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1221// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1191 1222
1192 //m_heartbeatTimer.Enabled = true; 1223 //m_heartbeatTimer.Enabled = true;
1193 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); 1224 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
1194 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1225 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1195 if (HeartbeatThread != null) 1226 if (m_heartbeatThread != null)
1196 { 1227 {
1197 m_hbRestarts++; 1228 m_hbRestarts++;
1198 if(m_hbRestarts > 10) 1229 if(m_hbRestarts > 10)
@@ -1208,13 +1239,13 @@ namespace OpenSim.Region.Framework.Scenes
1208//proc.WaitForExit(); 1239//proc.WaitForExit();
1209//Thread.Sleep(1000); 1240//Thread.Sleep(1000);
1210//Environment.Exit(1); 1241//Environment.Exit(1);
1211 HeartbeatThread.Abort(); 1242 m_heartbeatThread.Abort();
1212 Watchdog.AbortThread(HeartbeatThread.ManagedThreadId); 1243 Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId);
1213 HeartbeatThread = null; 1244 m_heartbeatThread = null;
1214 } 1245 }
1215 m_lastUpdate = Util.EnvironmentTickCount(); 1246// m_lastUpdate = Util.EnvironmentTickCount();
1216 1247
1217 HeartbeatThread 1248 m_heartbeatThread
1218 = Watchdog.StartThread( 1249 = Watchdog.StartThread(
1219 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); 1250 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
1220 } 1251 }
@@ -1245,34 +1276,97 @@ namespace OpenSim.Region.Framework.Scenes
1245 /// </summary> 1276 /// </summary>
1246 private void Heartbeat() 1277 private void Heartbeat()
1247 { 1278 {
1248 if (!Monitor.TryEnter(m_heartbeatLock)) 1279// if (!Monitor.TryEnter(m_heartbeatLock))
1249 { 1280// {
1250 Watchdog.RemoveThread(); 1281// Watchdog.RemoveThread();
1251 return; 1282// return;
1252 } 1283// }
1253 1284
1254 try 1285// try
1255 { 1286// {
1256 m_eventManager.TriggerOnRegionStarted(this);
1257 1287
1258 // The first frame can take a very long time due to physics actors being added on startup. Therefore, 1288 m_eventManager.TriggerOnRegionStarted(this);
1259 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1260 // alarms for scenes with many objects.
1261 Update(1);
1262 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1263 1289
1264 while (!shuttingdown) 1290 // The first frame can take a very long time due to physics actors being added on startup. Therefore,
1265 Update(-1); 1291 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1266 } 1292 // alarms for scenes with many objects.
1267 finally 1293 Update(1);
1268 { 1294
1269 Monitor.Pulse(m_heartbeatLock); 1295 Watchdog.StartThread(
1270 Monitor.Exit(m_heartbeatLock); 1296 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1271 } 1297
1298 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1299 Update(-1);
1300
1301// m_lastUpdate = Util.EnvironmentTickCount();
1302// m_firstHeartbeat = false;
1303// }
1304// finally
1305// {
1306// Monitor.Pulse(m_heartbeatLock);
1307// Monitor.Exit(m_heartbeatLock);
1308// }
1309
1310 Watchdog.RemoveThread();
1311 }
1312
1313 private void Maintenance()
1314 {
1315 DoMaintenance(-1);
1272 1316
1273 Watchdog.RemoveThread(); 1317 Watchdog.RemoveThread();
1274 } 1318 }
1275 1319
1320 public void DoMaintenance(int runs)
1321 {
1322 long? endRun = null;
1323 int runtc;
1324 int previousMaintenanceTick;
1325
1326 if (runs >= 0)
1327 endRun = MaintenanceRun + runs;
1328
1329 List<Vector3> coarseLocations;
1330 List<UUID> avatarUUIDs;
1331
1332 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun))
1333 {
1334 runtc = Util.EnvironmentTickCount();
1335 ++MaintenanceRun;
1336
1337 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1338 if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
1339 {
1340 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1341 // Send coarse locations to clients
1342 ForEachScenePresence(delegate(ScenePresence presence)
1343 {
1344 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1345 });
1346 }
1347
1348 Watchdog.UpdateThread();
1349
1350 previousMaintenanceTick = m_lastMaintenanceTick;
1351 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1352 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1353 runtc = (int)(MinMaintenanceTime * 1000) - runtc;
1354
1355 if (runtc > 0)
1356 Thread.Sleep(runtc);
1357
1358 // Optionally warn if a frame takes double the amount of time that it should.
1359 if (DebugUpdates
1360 && Util.EnvironmentTickCountSubtract(
1361 m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
1362 m_log.WarnFormat(
1363 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1364 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1365 MinMaintenanceTime * 1000,
1366 RegionInfo.RegionName);
1367 }
1368 }
1369
1276 public override void Update(int frames) 1370 public override void Update(int frames)
1277 { 1371 {
1278 long? endFrame = null; 1372 long? endFrame = null;
@@ -1284,10 +1378,8 @@ namespace OpenSim.Region.Framework.Scenes
1284 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; 1378 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
1285 int previousFrameTick; 1379 int previousFrameTick;
1286 int maintc; 1380 int maintc;
1287 List<Vector3> coarseLocations;
1288 List<UUID> avatarUUIDs;
1289 1381
1290 while (!shuttingdown && (endFrame == null || Frame < endFrame)) 1382 while (!m_shuttingDown && (endFrame == null || Frame < endFrame))
1291 { 1383 {
1292 maintc = Util.EnvironmentTickCount(); 1384 maintc = Util.EnvironmentTickCount();
1293 ++Frame; 1385 ++Frame;
@@ -1337,17 +1429,6 @@ namespace OpenSim.Region.Framework.Scenes
1337 if (Frame % m_update_presences == 0) 1429 if (Frame % m_update_presences == 0)
1338 m_sceneGraph.UpdatePresences(); 1430 m_sceneGraph.UpdatePresences();
1339 1431
1340 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1341 if (Frame % m_update_coarse_locations == 0)
1342 {
1343 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1344 // Send coarse locations to clients
1345 ForEachScenePresence(delegate(ScenePresence presence)
1346 {
1347 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1348 });
1349 }
1350
1351 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); 1432 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
1352 1433
1353 // Delete temp-on-rez stuff 1434 // Delete temp-on-rez stuff
@@ -1455,7 +1536,6 @@ namespace OpenSim.Region.Framework.Scenes
1455 1536
1456 EventManager.TriggerRegionHeartbeatEnd(this); 1537 EventManager.TriggerRegionHeartbeatEnd(this);
1457 1538
1458 // Tell the watchdog that this thread is still alive
1459 Watchdog.UpdateThread(); 1539 Watchdog.UpdateThread();
1460 1540
1461 previousFrameTick = m_lastFrameTick; 1541 previousFrameTick = m_lastFrameTick;
@@ -1463,15 +1543,11 @@ namespace OpenSim.Region.Framework.Scenes
1463 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc); 1543 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
1464 maintc = (int)(MinFrameTime * 1000) - maintc; 1544 maintc = (int)(MinFrameTime * 1000) - maintc;
1465 1545
1466 m_lastUpdate = Util.EnvironmentTickCount();
1467 m_firstHeartbeat = false; 1546 m_firstHeartbeat = false;
1468 1547
1469 if (maintc > 0) 1548 if (maintc > 0)
1470 Thread.Sleep(maintc); 1549 Thread.Sleep(maintc);
1471 1550
1472 m_lastUpdate = Util.EnvironmentTickCount();
1473 m_firstHeartbeat = false;
1474
1475 // Optionally warn if a frame takes double the amount of time that it should. 1551 // Optionally warn if a frame takes double the amount of time that it should.
1476 if (DebugUpdates 1552 if (DebugUpdates
1477 && Util.EnvironmentTickCountSubtract( 1553 && Util.EnvironmentTickCountSubtract(
@@ -2662,7 +2738,6 @@ namespace OpenSim.Region.Framework.Scenes
2662 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2738 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2663 2739
2664 CheckHeartbeat(); 2740 CheckHeartbeat();
2665 ScenePresence presence;
2666 2741
2667 ScenePresence sp = GetScenePresence(client.AgentId); 2742 ScenePresence sp = GetScenePresence(client.AgentId);
2668 2743
@@ -3253,7 +3328,7 @@ namespace OpenSim.Region.Framework.Scenes
3253 3328
3254 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3329 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3255 { 3330 {
3256 CheckHeartbeat(); 3331// CheckHeartbeat();
3257 bool isChildAgent = false; 3332 bool isChildAgent = false;
3258 ScenePresence avatar = GetScenePresence(agentID); 3333 ScenePresence avatar = GetScenePresence(agentID);
3259 if (avatar != null) 3334 if (avatar != null)
@@ -4700,7 +4775,7 @@ namespace OpenSim.Region.Framework.Scenes
4700 4775
4701 int health=1; // Start at 1, means we're up 4776 int health=1; // Start at 1, means we're up
4702 4777
4703 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) < 1000) 4778 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
4704 { 4779 {
4705 health+=1; 4780 health+=1;
4706 flags |= 1; 4781 flags |= 1;
@@ -4737,6 +4812,8 @@ Environment.Exit(1);
4737 // 4812 //
4738 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000) 4813 if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
4739 health++; 4814 health++;
4815 else
4816 return health;
4740 4817
4741 return health; 4818 return health;
4742 } 4819 }
@@ -4929,8 +5006,8 @@ Environment.Exit(1);
4929 if (m_firstHeartbeat) 5006 if (m_firstHeartbeat)
4930 return; 5007 return;
4931 5008
4932 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 5000) 5009 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000)
4933 StartTimer(); 5010 Start();
4934 } 5011 }
4935 5012
4936 public override ISceneObject DeserializeObject(string representation) 5013 public override ISceneObject DeserializeObject(string representation)