diff options
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 94 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneBase.cs | 3 |
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 | ||