aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs94
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs3
2 files changed, 62 insertions, 35 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a43de29..53001e9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -329,6 +329,17 @@ namespace OpenSim.Region.Framework.Scenes
329 private Dictionary<string, string> m_extraSettings; 329 private Dictionary<string, string> m_extraSettings;
330 330
331 /// <summary> 331 /// <summary>
332 /// If true then the next time the scene loop is activated, updates will be performed by firing of a timer
333 /// rather than on a single thread that sleeps.
334 /// </summary>
335 public bool UpdateOnTimer { get; set; }
336
337 /// <summary>
338 /// Only used if we are updating scene on a timer rather than sleeping a thread.
339 /// </summary>
340 private Timer m_sceneUpdateTimer;
341
342 /// <summary>
332 /// Current scene frame number 343 /// Current scene frame number
333 /// </summary> 344 /// </summary>
334 public uint Frame 345 public uint Frame
@@ -430,7 +441,8 @@ namespace OpenSim.Region.Framework.Scenes
430 /// Is the scene active? 441 /// Is the scene active?
431 /// </summary> 442 /// </summary>
432 /// <remarks> 443 /// <remarks>
433 /// If false, maintenance and update loops are not being run. Updates can still be triggered manually if 444 /// If false, maintenance and update loops are not being run, though after setting to false update may still
445 /// be active for a period (and IsRunning will still be true). Updates can still be triggered manually if
434 /// the scene is not active. 446 /// the scene is not active.
435 /// </remarks> 447 /// </remarks>
436 public bool Active 448 public bool Active
@@ -453,8 +465,11 @@ namespace OpenSim.Region.Framework.Scenes
453 } 465 }
454 private volatile bool m_active; 466 private volatile bool m_active;
455 467
456// private int m_lastUpdate; 468 /// <summary>
457// private bool m_firstHeartbeat = true; 469 /// If true then updates are running. This may be true for a short period after a scene is de-activated.
470 /// </summary>
471 public bool IsRunning { get { return m_isRunning; } }
472 private volatile bool m_isRunning;
458 473
459 private Timer m_mapGenerationTimer = new Timer(); 474 private Timer m_mapGenerationTimer = new Timer();
460 private bool m_generateMaptiles; 475 private bool m_generateMaptiles;
@@ -1352,19 +1367,18 @@ namespace OpenSim.Region.Framework.Scenes
1352 /// </param> 1367 /// </param>
1353 public void Start(bool startScripts) 1368 public void Start(bool startScripts)
1354 { 1369 {
1370 if (IsRunning)
1371 return;
1372
1373 m_isRunning = true;
1355 m_active = true; 1374 m_active = true;
1356 1375
1357// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1376// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1358
1359 //m_heartbeatTimer.Enabled = true;
1360 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
1361 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1362 if (m_heartbeatThread != null) 1377 if (m_heartbeatThread != null)
1363 { 1378 {
1364 m_heartbeatThread.Abort(); 1379 m_heartbeatThread.Abort();
1365 m_heartbeatThread = null; 1380 m_heartbeatThread = null;
1366 } 1381 }
1367// m_lastUpdate = Util.EnvironmentTickCount();
1368 1382
1369 m_heartbeatThread 1383 m_heartbeatThread
1370 = Watchdog.StartThread( 1384 = Watchdog.StartThread(
@@ -1401,15 +1415,6 @@ namespace OpenSim.Region.Framework.Scenes
1401 /// </summary> 1415 /// </summary>
1402 private void Heartbeat() 1416 private void Heartbeat()
1403 { 1417 {
1404// if (!Monitor.TryEnter(m_heartbeatLock))
1405// {
1406// Watchdog.RemoveThread();
1407// return;
1408// }
1409
1410// try
1411// {
1412
1413 m_eventManager.TriggerOnRegionStarted(this); 1418 m_eventManager.TriggerOnRegionStarted(this);
1414 1419
1415 // The first frame can take a very long time due to physics actors being added on startup. Therefore, 1420 // The first frame can take a very long time due to physics actors being added on startup. Therefore,
@@ -1418,21 +1423,37 @@ namespace OpenSim.Region.Framework.Scenes
1418 Update(1); 1423 Update(1);
1419 1424
1420 Watchdog.StartThread( 1425 Watchdog.StartThread(
1421 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); 1426 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1422 1427
1423 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1428 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1424 Update(-1);
1425 1429
1426// m_lastUpdate = Util.EnvironmentTickCount(); 1430 if (UpdateOnTimer)
1427// m_firstHeartbeat = false; 1431 {
1428// } 1432 m_sceneUpdateTimer = new Timer(MinFrameTime * 1000);
1429// finally 1433 m_sceneUpdateTimer.AutoReset = true;
1430// { 1434 m_sceneUpdateTimer.Elapsed += Update;
1431// Monitor.Pulse(m_heartbeatLock); 1435 m_sceneUpdateTimer.Start();
1432// Monitor.Exit(m_heartbeatLock); 1436 }
1433// } 1437 else
1438 {
1439 Update(-1);
1440 Watchdog.RemoveThread();
1441 m_isRunning = false;
1442 }
1443 }
1434 1444
1435 Watchdog.RemoveThread(); 1445 private void Update(object sender, ElapsedEventArgs e)
1446 {
1447 // If the last frame did not complete on time, then immediately start the next update on the same thread
1448 // and ignore further timed updates until we have a frame that had spare time.
1449 while (!Update(1) && Active) {}
1450
1451 if (!Active || m_shuttingDown)
1452 {
1453 m_sceneUpdateTimer.Stop();
1454 m_sceneUpdateTimer = null;
1455 m_isRunning = false;
1456 }
1436 } 1457 }
1437 1458
1438 private void Maintenance() 1459 private void Maintenance()
@@ -1502,7 +1523,7 @@ namespace OpenSim.Region.Framework.Scenes
1502 } 1523 }
1503 } 1524 }
1504 1525
1505 public override void Update(int frames) 1526 public override bool Update(int frames)
1506 { 1527 {
1507 long? endFrame = null; 1528 long? endFrame = null;
1508 1529
@@ -1652,7 +1673,8 @@ namespace OpenSim.Region.Framework.Scenes
1652 1673
1653 EventManager.TriggerRegionHeartbeatEnd(this); 1674 EventManager.TriggerRegionHeartbeatEnd(this);
1654 1675
1655 Watchdog.UpdateThread(); 1676 if (!UpdateOnTimer)
1677 Watchdog.UpdateThread();
1656 1678
1657 previousFrameTick = m_lastFrameTick; 1679 previousFrameTick = m_lastFrameTick;
1658 m_lastFrameTick = Util.EnvironmentTickCount(); 1680 m_lastFrameTick = Util.EnvironmentTickCount();
@@ -1661,9 +1683,11 @@ namespace OpenSim.Region.Framework.Scenes
1661 1683
1662 if (tmpMS > 0) 1684 if (tmpMS > 0)
1663 { 1685 {
1664 Thread.Sleep(tmpMS); 1686 spareMS = tmpMS;
1665 spareMS += tmpMS; 1687
1666 } 1688 if (!UpdateOnTimer)
1689 Thread.Sleep(tmpMS);
1690 }
1667 1691
1668 frameMS = Util.EnvironmentTickCountSubtract(maintc); 1692 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1669 maintc = Util.EnvironmentTickCount(); 1693 maintc = Util.EnvironmentTickCount();
@@ -1683,7 +1707,7 @@ namespace OpenSim.Region.Framework.Scenes
1683 StatsReporter.AddSpareMS(spareMS); 1707 StatsReporter.AddSpareMS(spareMS);
1684 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); 1708 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1685 1709
1686 // Optionally warn if a frame takes double the amount of time that it should. 1710 // Optionally warn if a frame takes double the amount of time that it should.
1687 if (DebugUpdates 1711 if (DebugUpdates
1688 && Util.EnvironmentTickCountSubtract( 1712 && Util.EnvironmentTickCountSubtract(
1689 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2)) 1713 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
@@ -1693,6 +1717,8 @@ namespace OpenSim.Region.Framework.Scenes
1693 MinFrameTime * 1000, 1717 MinFrameTime * 1000,
1694 RegionInfo.RegionName); 1718 RegionInfo.RegionName);
1695 } 1719 }
1720
1721 return spareMS >= 0;
1696 } 1722 }
1697 1723
1698 public void AddGroupTarget(SceneObjectGroup grp) 1724 public void AddGroupTarget(SceneObjectGroup grp)
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 0445268..aaddce6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -196,7 +196,8 @@ namespace OpenSim.Region.Framework.Scenes
196 /// Number of frames to update. Exits on shutdown even if there are frames remaining. 196 /// Number of frames to update. Exits on shutdown even if there are frames remaining.
197 /// If -1 then updates until shutdown. 197 /// If -1 then updates until shutdown.
198 /// </param> 198 /// </param>
199 public abstract void Update(int frames); 199 /// <returns>true if update completed within minimum frame time, false otherwise.</returns>
200 public abstract bool Update(int frames);
200 201
201 #endregion 202 #endregion
202 203