From 25592bbd852e9350bca25f240d6d54c7a54e28a0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 12 Mar 2012 21:16:05 +0000
Subject: Add max thread and min thread information to "xengine status" region
console command
---
OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 3 +++
1 file changed, 3 insertions(+)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index bc1902b..4010167 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -578,7 +578,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
return true;
if (!m_InSelfDelete)
+ {
+// m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID);
result.Abort();
+ }
lock (m_EventQueue)
{
--
cgit v1.1
From 95ec96bf86ebebbc6c2f2c3f3a2bd8ce3f9990f4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 14 Mar 2012 00:29:36 +0000
Subject: refactor: rename ScriptInstance.m_CurrentResult to m_CurrentWorkItem
to make it more understandable as to what it is and what it does (hold a
thread pool work item for a waiting of in-progress event)
Also add other various illustrative comments
---
.../ScriptEngine/Shared/Instance/ScriptInstance.cs | 66 ++++++++++++++--------
1 file changed, 44 insertions(+), 22 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 4010167..b840730 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -58,7 +58,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IScriptEngine m_Engine;
- private IScriptWorkItem m_CurrentResult = null;
+
+ ///
+ /// The current work item if an event for this script is running or waiting to run,
+ ///
+ ///
+ /// Null if there is no running or waiting to run event. Must be changed only under an m_EventQueue lock.
+ ///
+ private IScriptWorkItem m_CurrentWorkItem;
+
private Queue m_EventQueue = new Queue(32);
private bool m_RunEvents = false;
private UUID m_ItemID;
@@ -157,7 +165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
// Need to place ourselves back in a work item if there are events to process
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
- m_CurrentResult = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
}
}
@@ -527,8 +535,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (m_EventQueue.Count > 0)
{
- if (m_CurrentResult == null)
- m_CurrentResult = m_Engine.QueueEventHandler(this);
+ if (m_CurrentWorkItem == null)
+ m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
// else
// m_log.Error("[Script] Tried to start a script that was already queued");
}
@@ -540,52 +548,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// m_log.DebugFormat(
// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout);
- IScriptWorkItem result;
+ IScriptWorkItem workItem;
lock (m_EventQueue)
{
if (!Running)
return true;
- if (m_CurrentResult == null)
+ // If we're not running or waiting to run an event then we can safely stop.
+ if (m_CurrentWorkItem == null)
{
m_RunEvents = false;
return true;
}
- if (m_CurrentResult.Cancel())
+ // If we are waiting to run an event then we can try to cancel it.
+ if (m_CurrentWorkItem.Cancel())
{
- m_CurrentResult = null;
+ m_CurrentWorkItem = null;
m_RunEvents = false;
return true;
}
- result = m_CurrentResult;
+ workItem = m_CurrentWorkItem;
m_RunEvents = false;
}
- if (result.Wait(new TimeSpan((long)timeout * 100000)))
+ // Wait for the current event to complete.
+ if (workItem.Wait(new TimeSpan((long)timeout * 100000)))
{
return true;
}
lock (m_EventQueue)
{
- result = m_CurrentResult;
+ workItem = m_CurrentWorkItem;
}
- if (result == null)
+ if (workItem == null)
return true;
+ // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then
+ // forcibly abort the work item (this aborts the underlying thread).
if (!m_InSelfDelete)
{
// m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID);
- result.Abort();
+
+ workItem.Abort();
}
lock (m_EventQueue)
{
- m_CurrentResult = null;
+ m_CurrentWorkItem = null;
}
return true;
@@ -606,6 +620,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
throw new EventAbortException();
}
+ ///
+ /// Post an event to this script instance.
+ ///
+ ///
+ /// The request to run the event is sent
+ ///
+ ///
public void PostEvent(EventParams data)
{
// m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}",
@@ -672,9 +693,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_EventQueue.Enqueue(data);
- if (m_CurrentResult == null)
+ if (m_CurrentWorkItem == null)
{
- m_CurrentResult = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
}
}
@@ -701,11 +722,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
{
- m_CurrentResult = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
else
{
- m_CurrentResult = null;
+ m_CurrentWorkItem = null;
}
return 0;
}
@@ -825,15 +846,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
}
+
+ // If there are more events and we are currently running and not shutting down, then ask the
+ // script engine to run the next event.
lock (m_EventQueue)
{
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
{
- m_CurrentResult = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
else
{
- m_CurrentResult = null;
+ m_CurrentWorkItem = null;
}
}
@@ -943,8 +967,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void SaveState(string assembly)
{
-
-
// If we're currently in an event, just tell it to save upon return
//
if (m_InEvent)
--
cgit v1.1
From 12cebb12d5b095fc8d1a2936b9537ad0e0e7dbe7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Mar 2012 00:06:52 +0000
Subject: Alleviate an issue where calling Thread.Abort() on script WorkItems
can fail to release locks, resulting in a crippled simulator.
This seems to be a particular problem with ReaderWriterLockSlim, though other locks can be affected as well.
It has been seen to happen when llDie() is called in a linkset running more than one script.
Alleviation here means supplying a ScriptInstance.Stop() timeout of 1000ms rather than 0ms, to give events a chance to complete.
Also, we check the IsRunning status at the top of the ScriptInstance.EventProcessor() so that another event doesn't start in the mean time.
Ultimately, a better solution may have to be found since a long-running event would still exceed the timeout and be aborted.
---
.../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index b840730..6a9cd72 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -546,7 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public bool Stop(int timeout)
{
// m_log.DebugFormat(
-// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout);
+// "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}",
+// ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks);
IScriptWorkItem workItem;
@@ -575,7 +576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
// Wait for the current event to complete.
- if (workItem.Wait(new TimeSpan((long)timeout * 100000)))
+ if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000)))
{
return true;
}
@@ -592,7 +593,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// forcibly abort the work item (this aborts the underlying thread).
if (!m_InSelfDelete)
{
-// m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID);
+// m_log.ErrorFormat(
+// "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}",
+// ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks);
workItem.Abort();
}
@@ -706,6 +709,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
///
public object EventProcessor()
{
+ // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
+ if (!Running)
+ return 0;
+
lock (m_Script)
{
// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
--
cgit v1.1
From 5ddda892388fe22912d8992f1c9d24b3667926f0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Mar 2012 00:48:19 +0000
Subject: Remove duplication of m_RunEvents and Running
---
.../ScriptEngine/Shared/Instance/ScriptInstance.cs | 28 +++++++++-------------
1 file changed, 11 insertions(+), 17 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6a9cd72..cc4be73 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -68,7 +68,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
private IScriptWorkItem m_CurrentWorkItem;
private Queue m_EventQueue = new Queue(32);
- private bool m_RunEvents = false;
private UUID m_ItemID;
private uint m_LocalID;
private UUID m_ObjectID;
@@ -141,11 +140,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
}
- public bool Running
- {
- get { return m_RunEvents; }
- set { m_RunEvents = value; }
- }
+ public bool Running { get; set; }
public bool Suspended
{
@@ -164,7 +159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
lock (m_EventQueue)
{
// Need to place ourselves back in a work item if there are events to process
- if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
+ if ((m_EventQueue.Count > 0) && Running && (!m_ShuttingDown))
m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
}
@@ -369,13 +364,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
part.SetScriptEvents(m_ItemID,
(int)m_Script.GetStateEventFlags(State));
- if (m_RunEvents && (!m_ShuttingDown))
+ if (Running && (!m_ShuttingDown))
{
- m_RunEvents = false;
+ Running = false;
}
else
{
- m_RunEvents = false;
+ Running = false;
m_startOnInit = false;
}
@@ -531,7 +526,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (Running)
return;
- m_RunEvents = true;
+ Running = true;
if (m_EventQueue.Count > 0)
{
@@ -559,7 +554,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// If we're not running or waiting to run an event then we can safely stop.
if (m_CurrentWorkItem == null)
{
- m_RunEvents = false;
+ Running = false;
return true;
}
@@ -567,12 +562,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (m_CurrentWorkItem.Cancel())
{
m_CurrentWorkItem = null;
- m_RunEvents = false;
+ Running = false;
return true;
}
workItem = m_CurrentWorkItem;
- m_RunEvents = false;
+ Running = false;
}
// Wait for the current event to complete.
@@ -727,7 +722,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
data = (EventParams) m_EventQueue.Dequeue();
if (data == null) // Shouldn't happen
{
- if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
+ if (m_EventQueue.Count > 0 && Running && !m_ShuttingDown)
{
m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
@@ -853,12 +848,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
}
-
// If there are more events and we are currently running and not shutting down, then ask the
// script engine to run the next event.
lock (m_EventQueue)
{
- if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
+ if (m_EventQueue.Count > 0 && Running && (!m_ShuttingDown))
{
m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
}
--
cgit v1.1
From f0c1746063dff537d83babcf617b7cf88ed612dc Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Mar 2012 01:26:38 +0000
Subject: minor: correct indentation levels
---
.../ScriptEngine/Shared/Instance/ScriptInstance.cs | 25 +++++++++++-----------
1 file changed, 12 insertions(+), 13 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index cc4be73..afa9191 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -282,19 +282,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
m_Apis[api] = am.CreateApi(api);
m_Apis[api].Initialize(engine, part, m_LocalID, itemID);
- }
-
- try
- {
- if (dom != System.AppDomain.CurrentDomain)
- m_Script = (IScript)dom.CreateInstanceAndUnwrap(
- Path.GetFileNameWithoutExtension(assembly),
- "SecondLife.Script");
- else
- m_Script = (IScript)Assembly.Load(
- Path.GetFileNameWithoutExtension(assembly)).CreateInstance(
- "SecondLife.Script");
-
+ }
+
+ try
+ {
+ if (dom != System.AppDomain.CurrentDomain)
+ m_Script = (IScript)dom.CreateInstanceAndUnwrap(
+ Path.GetFileNameWithoutExtension(assembly),
+ "SecondLife.Script");
+ else
+ m_Script = (IScript)Assembly.Load(
+ Path.GetFileNameWithoutExtension(assembly)).CreateInstance(
+ "SecondLife.Script");
//ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
//RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
--
cgit v1.1
From 2d32401e23f216565f64163fb3220d035e45b0a8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Mar 2012 01:32:16 +0000
Subject: Simplify some logic in the ScriptInstance constructor - running is
set to false in both if/else branches
---
.../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index afa9191..8b0dbaa 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -363,15 +363,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
part.SetScriptEvents(m_ItemID,
(int)m_Script.GetStateEventFlags(State));
- if (Running && (!m_ShuttingDown))
- {
- Running = false;
- }
- else
- {
- Running = false;
+ Running = false;
+
+ if (m_ShuttingDown)
m_startOnInit = false;
- }
// we get new rez events on sim restart, too
// but if there is state, then we fire the change
@@ -380,7 +375,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// We loaded state, don't force a re-save
m_SaveState = false;
m_startedFromSavedState = true;
-
}
}
else
--
cgit v1.1
From acb1355ff203b55ae2581b5606e251b8fa91b252 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 15 Mar 2012 02:02:31 +0000
Subject: Remove property/field duplication in ScriptInstance where it's
unnecessary.
---
.../ScriptEngine/Shared/Instance/ScriptInstance.cs | 277 ++++++++-------------
1 file changed, 107 insertions(+), 170 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 8b0dbaa..968351b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -56,43 +56,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public class ScriptInstance : MarshalByRefObject, IScriptInstance
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
- private IScriptEngine m_Engine;
///
/// The current work item if an event for this script is running or waiting to run,
///
///
- /// Null if there is no running or waiting to run event. Must be changed only under an m_EventQueue lock.
+ /// Null if there is no running or waiting to run event. Must be changed only under an EventQueue lock.
///
private IScriptWorkItem m_CurrentWorkItem;
- private Queue m_EventQueue = new Queue(32);
- private UUID m_ItemID;
- private uint m_LocalID;
- private UUID m_ObjectID;
- private UUID m_AssetID;
private IScript m_Script;
- private UUID m_AppDomain;
private DetectParams[] m_DetectParams;
private bool m_TimerQueued;
private DateTime m_EventStart;
private bool m_InEvent;
- private string m_PrimName;
- private string m_ScriptName;
private string m_Assembly;
- private int m_StartParam;
private string m_CurrentEvent = String.Empty;
private bool m_InSelfDelete;
private int m_MaxScriptQueue;
private bool m_SaveState = true;
- private bool m_ShuttingDown;
private int m_ControlEventsInQueue;
private int m_LastControlLevel;
private bool m_CollisionInQueue;
- private TaskInventoryItem m_thisScriptTask;
+
// The following is for setting a minimum delay between events
private double m_minEventDelay;
+
private long m_eventDelayTicks;
private long m_nextEventTimeTicks;
private bool m_startOnInit = true;
@@ -103,21 +92,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
private UUID m_CurrentStateHash;
private UUID m_RegionID;
- private Dictionary, KeyValuePair>
- m_LineMap;
-
- public Dictionary, KeyValuePair>
- LineMap
- {
- get { return m_LineMap; }
- set { m_LineMap = value; }
- }
+ public Dictionary, KeyValuePair> LineMap { get; set; }
private Dictionary m_Apis = new Dictionary();
- // Script state
- private string m_State = "default";
-
public Object[] PluginData = new Object[0];
///
@@ -156,11 +134,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (wasSuspended && !m_Suspended)
{
- lock (m_EventQueue)
+ lock (EventQueue)
{
// Need to place ourselves back in a work item if there are events to process
- if ((m_EventQueue.Count > 0) && Running && (!m_ShuttingDown))
- m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
+ if (EventQueue.Count > 0 && Running && !ShuttingDown)
+ m_CurrentWorkItem = Engine.QueueEventHandler(this);
}
}
}
@@ -168,79 +146,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
private bool m_Suspended;
- public bool ShuttingDown
- {
- get { return m_ShuttingDown; }
- set { m_ShuttingDown = value; }
- }
+ public bool ShuttingDown { get; set; }
- public string State
- {
- get { return m_State; }
- set { m_State = value; }
- }
+ public string State { get; set; }
- public IScriptEngine Engine
- {
- get { return m_Engine; }
- }
+ public IScriptEngine Engine { get; private set; }
- public UUID AppDomain
- {
- get { return m_AppDomain; }
- set { m_AppDomain = value; }
- }
+ public UUID AppDomain { get; set; }
- public string PrimName
- {
- get { return m_PrimName; }
- }
+ public string PrimName { get; private set; }
- public string ScriptName
- {
- get { return m_ScriptName; }
- }
+ public string ScriptName { get; private set; }
- public UUID ItemID
- {
- get { return m_ItemID; }
- }
+ public UUID ItemID { get; private set; }
- public UUID ObjectID
- {
- get { return m_ObjectID; }
- }
+ public UUID ObjectID { get; private set; }
- public uint LocalID
- {
- get { return m_LocalID; }
- }
+ public uint LocalID { get; private set; }
- public UUID AssetID
- {
- get { return m_AssetID; }
- }
+ public UUID AssetID { get; private set; }
- public Queue EventQueue
- {
- get { return m_EventQueue; }
- }
+ public Queue EventQueue { get; private set; }
- public void ClearQueue()
- {
- m_TimerQueued = false;
- m_EventQueue.Clear();
- }
+ public int StartParam { get; set; }
- public int StartParam
- {
- get { return m_StartParam; }
- set { m_StartParam = value; }
- }
+ public TaskInventoryItem ScriptTask { get; private set; }
- public TaskInventoryItem ScriptTask
+ public void ClearQueue()
{
- get { return m_thisScriptTask; }
+ m_TimerQueued = false;
+ EventQueue.Clear();
}
public ScriptInstance(IScriptEngine engine, SceneObjectPart part,
@@ -249,16 +184,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
int startParam, bool postOnRez, StateSource stateSource,
int maxScriptQueue)
{
- m_Engine = engine;
-
- m_LocalID = part.LocalId;
- m_ObjectID = part.UUID;
- m_ItemID = itemID;
- m_AssetID = assetID;
- m_PrimName = primName;
- m_ScriptName = scriptName;
+ State = "default";
+ EventQueue = new Queue(32);
+
+ Engine = engine;
+ LocalID = part.LocalId;
+ ObjectID = part.UUID;
+ ItemID = itemID;
+ AssetID = assetID;
+ PrimName = primName;
+ ScriptName = scriptName;
m_Assembly = assembly;
- m_StartParam = startParam;
+ StartParam = startParam;
m_MaxScriptQueue = maxScriptQueue;
m_stateSource = stateSource;
m_postOnRez = postOnRez;
@@ -269,9 +206,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
lock (part.TaskInventory)
{
- if (part.TaskInventory.ContainsKey(m_ItemID))
+ if (part.TaskInventory.ContainsKey(ItemID))
{
- m_thisScriptTask = part.TaskInventory[m_ItemID];
+ ScriptTask = part.TaskInventory[ItemID];
}
}
}
@@ -281,7 +218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
foreach (string api in am.GetApis())
{
m_Apis[api] = am.CreateApi(api);
- m_Apis[api].Initialize(engine, part, m_LocalID, itemID);
+ m_Apis[api].Initialize(engine, part, LocalID, itemID);
}
try
@@ -315,7 +252,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// // m_log.Debug("[Script] Script instance created");
- part.SetScriptEvents(m_ItemID,
+ part.SetScriptEvents(ItemID,
(int)m_Script.GetStateEventFlags(State));
}
catch (Exception e)
@@ -330,7 +267,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_SaveState = true;
string savedState = Path.Combine(Path.GetDirectoryName(assembly),
- m_ItemID.ToString() + ".state");
+ ItemID.ToString() + ".state");
if (File.Exists(savedState))
{
string xml = String.Empty;
@@ -354,18 +291,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
ScriptSerializer.Deserialize(xml, this);
- AsyncCommandManager.CreateFromData(m_Engine,
- m_LocalID, m_ItemID, m_ObjectID,
+ AsyncCommandManager.CreateFromData(Engine,
+ LocalID, ItemID, ObjectID,
PluginData);
-// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName);
+// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName);
- part.SetScriptEvents(m_ItemID,
+ part.SetScriptEvents(ItemID,
(int)m_Script.GetStateEventFlags(State));
Running = false;
- if (m_ShuttingDown)
+ if (ShuttingDown)
m_startOnInit = false;
// we get new rez events on sim restart, too
@@ -393,7 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
// else
// {
-// ScenePresence presence = m_Engine.World.GetScenePresence(part.OwnerID);
+// ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID);
// if (presence != null && (!postOnRez))
// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
@@ -411,7 +348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (m_postOnRez)
{
PostEvent(new EventParams("on_rez",
- new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0]));
+ new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
}
if (m_stateSource == StateSource.AttachedRez)
@@ -445,7 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (m_postOnRez)
{
PostEvent(new EventParams("on_rez",
- new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0]));
+ new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
}
if (m_stateSource == StateSource.AttachedRez)
@@ -459,7 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
private void ReleaseControls()
{
- SceneObjectPart part = m_Engine.World.GetSceneObjectPart(m_LocalID);
+ SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
if (part != null)
{
@@ -467,18 +404,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
UUID permsGranter;
lock (part.TaskInventory)
{
- if (!part.TaskInventory.ContainsKey(m_ItemID))
+ if (!part.TaskInventory.ContainsKey(ItemID))
return;
- permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
- permsMask = part.TaskInventory[m_ItemID].PermsMask;
+ permsGranter = part.TaskInventory[ItemID].PermsGranter;
+ permsMask = part.TaskInventory[ItemID].PermsMask;
}
if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
{
- ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter);
+ ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
if (presence != null)
- presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID);
+ presence.UnRegisterControlEventsToScript(LocalID, ItemID);
}
}
}
@@ -486,13 +423,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void DestroyScriptInstance()
{
ReleaseControls();
- AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
+ AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
}
public void RemoveState()
{
string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly),
- m_ItemID.ToString() + ".state");
+ ItemID.ToString() + ".state");
try
{
@@ -505,7 +442,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void VarDump(Dictionary vars)
{
- // m_log.Info("Variable dump for script "+ m_ItemID.ToString());
+ // m_log.Info("Variable dump for script "+ ItemID.ToString());
// foreach (KeyValuePair v in vars)
// {
// m_log.Info("Variable: "+v.Key+" = "+v.Value.ToString());
@@ -514,17 +451,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void Start()
{
- lock (m_EventQueue)
+ lock (EventQueue)
{
if (Running)
return;
Running = true;
- if (m_EventQueue.Count > 0)
+ if (EventQueue.Count > 0)
{
if (m_CurrentWorkItem == null)
- m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = Engine.QueueEventHandler(this);
// else
// m_log.Error("[Script] Tried to start a script that was already queued");
}
@@ -539,7 +476,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
IScriptWorkItem workItem;
- lock (m_EventQueue)
+ lock (EventQueue)
{
if (!Running)
return true;
@@ -569,7 +506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
return true;
}
- lock (m_EventQueue)
+ lock (EventQueue)
{
workItem = m_CurrentWorkItem;
}
@@ -588,7 +525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
workItem.Abort();
}
- lock (m_EventQueue)
+ lock (EventQueue)
{
m_CurrentWorkItem = null;
}
@@ -621,7 +558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public void PostEvent(EventParams data)
{
// m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}",
-// m_PrimName, m_ScriptName, data.EventName, m_State);
+// PrimName, ScriptName, data.EventName, State);
if (!Running)
return;
@@ -636,9 +573,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks;
}
- lock (m_EventQueue)
+ lock (EventQueue)
{
- if (m_EventQueue.Count >= m_MaxScriptQueue)
+ if (EventQueue.Count >= m_MaxScriptQueue)
return;
if (data.EventName == "timer")
@@ -682,11 +619,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_CollisionInQueue = true;
}
- m_EventQueue.Enqueue(data);
+ EventQueue.Enqueue(data);
if (m_CurrentWorkItem == null)
{
- m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = Engine.QueueEventHandler(this);
}
}
}
@@ -710,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
EventParams data = null;
- lock (m_EventQueue)
+ lock (EventQueue)
{
- data = (EventParams) m_EventQueue.Dequeue();
+ data = (EventParams)EventQueue.Dequeue();
if (data == null) // Shouldn't happen
{
- if (m_EventQueue.Count > 0 && Running && !m_ShuttingDown)
+ if (EventQueue.Count > 0 && Running && !ShuttingDown)
{
- m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = Engine.QueueEventHandler(this);
}
else
{
@@ -744,28 +681,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (data.EventName == "state") // Hardcoded state change
{
// m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
- // m_PrimName, m_ScriptName, data.Params[0].ToString());
- m_State = data.Params[0].ToString();
- AsyncCommandManager.RemoveScript(m_Engine,
- m_LocalID, m_ItemID);
+ // PrimName, ScriptName, data.Params[0].ToString());
+ State = data.Params[0].ToString();
+ AsyncCommandManager.RemoveScript(Engine,
+ LocalID, ItemID);
- SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
- m_LocalID);
+ SceneObjectPart part = Engine.World.GetSceneObjectPart(
+ LocalID);
if (part != null)
{
- part.SetScriptEvents(m_ItemID,
+ part.SetScriptEvents(ItemID,
(int)m_Script.GetStateEventFlags(State));
}
}
else
{
- if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
+ if (Engine.World.PipeEventsForScript(LocalID) ||
data.EventName == "control") // Don't freeze avies!
{
- SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
- m_LocalID);
+ SceneObjectPart part = Engine.World.GetSceneObjectPart(
+ LocalID);
// m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
- // m_PrimName, m_ScriptName, data.EventName, m_State);
+ // PrimName, ScriptName, data.EventName, State);
try
{
@@ -807,7 +744,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
if (text.Length > 1000)
text = text.Substring(0, 1000);
- m_Engine.World.SimChat(Utils.StringToBytes(text),
+ Engine.World.SimChat(Utils.StringToBytes(text),
ChatTypeEnum.DebugChannel, 2147483647,
part.AbsolutePosition,
part.Name, part.UUID, false);
@@ -829,13 +766,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
m_InSelfDelete = true;
if (part != null)
- m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
+ Engine.World.DeleteSceneObject(part.ParentGroup, false);
}
else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
{
m_InSelfDelete = true;
if (part != null)
- part.Inventory.RemoveInventoryItem(m_ItemID);
+ part.Inventory.RemoveInventoryItem(ItemID);
}
}
}
@@ -843,11 +780,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// If there are more events and we are currently running and not shutting down, then ask the
// script engine to run the next event.
- lock (m_EventQueue)
+ lock (EventQueue)
{
- if (m_EventQueue.Count > 0 && Running && (!m_ShuttingDown))
+ if (EventQueue.Count > 0 && Running && !ShuttingDown)
{
- m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
+ m_CurrentWorkItem = Engine.QueueEventHandler(this);
}
else
{
@@ -880,15 +817,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
ReleaseControls();
Stop(0);
- SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID);
- part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0;
- part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero;
- AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
- m_EventQueue.Clear();
+ SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
+ part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
+ part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
+ AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
+ EventQueue.Clear();
m_Script.ResetVars();
- m_State = "default";
+ State = "default";
- part.SetScriptEvents(m_ItemID,
+ part.SetScriptEvents(ItemID,
(int)m_Script.GetStateEventFlags(State));
if (running)
Start();
@@ -905,16 +842,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
ReleaseControls();
m_Script.ResetVars();
- SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID);
- part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0;
- part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero;
- AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
+ SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
+ part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
+ part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
+ AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
- m_EventQueue.Clear();
+ EventQueue.Clear();
m_Script.ResetVars();
- m_State = "default";
+ State = "default";
- part.SetScriptEvents(m_ItemID,
+ part.SetScriptEvents(ItemID,
(int)m_Script.GetStateEventFlags(State));
if (m_CurrentEvent != "state_entry")
@@ -969,7 +906,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
return;
}
- PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
+ PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
string xml = ScriptSerializer.Serialize(this);
@@ -981,7 +918,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
try
{
- FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"));
+ FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state"));
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
Byte[] buf = enc.GetBytes(xml);
fs.Write(buf, 0, buf.Length);
@@ -991,7 +928,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
{
// m_log.Error("Unable to save xml\n"+e.ToString());
}
- //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")))
+ //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")))
//{
// throw new Exception("Completed persistence save, but no file was created");
//}
@@ -1008,7 +945,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public override string ToString()
{
- return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName);
+ return String.Format("{0} {1} on {2}", ScriptName, ItemID, PrimName);
}
string FormatException(Exception e)
@@ -1076,7 +1013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// Force an update of the in-memory plugin data
//
- PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
+ PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
return ScriptSerializer.Serialize(this);
}
--
cgit v1.1
From a4b01ef38a735ffe70b402061871a9c99f2757ed Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 16 Mar 2012 00:34:30 +0000
Subject: Replace script-lines-per-second with the script execution time scaled
by its measurement period and an idealised frame time.
The previous lines-per-second measurement used for top scripts report was inaccurate, since lines executed does not reflect time taken to execute.
Also, every fetch of the report would reset all the numbers limiting its usefulness and we weren't even guaranteed to see the top 100.
The actual measurement value should be script execution time per frame but XEngine does not work this way.
Therefore, we use actual script execution time scaled by the measurement period and an idealised frame time.
This is still not ideal but gives reasonable results and allows scripts to be compared.
This commit moves script execution time calculations from SceneGraph into IScriptModule implementations.
---
.../ScriptEngine/Shared/Instance/ScriptInstance.cs | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 968351b..b177287 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -172,6 +172,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public TaskInventoryItem ScriptTask { get; private set; }
+ public DateTime TimeStarted { get; private set; }
+
+ public long MeasurementPeriodTickStart { get; private set; }
+
+ public long MeasurementPeriodExecutionTime { get; private set; }
+
+ public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute;
+
public void ClearQueue()
{
m_TimerQueued = false;
@@ -458,6 +466,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
Running = true;
+ TimeStarted = DateTime.Now;
+ MeasurementPeriodTickStart = Util.EnvironmentTickCount();
+ MeasurementPeriodExecutionTime = 0;
+
if (EventQueue.Count > 0)
{
if (m_CurrentWorkItem == null)
@@ -710,8 +722,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_EventStart = DateTime.Now;
m_InEvent = true;
+ int start = Util.EnvironmentTickCount();
+
+ // Reset the measurement period when we reach the end of the current one.
+ if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod)
+ MeasurementPeriodTickStart = start;
+
m_Script.ExecuteEvent(State, data.EventName, data.Params);
+ MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start;
+
m_InEvent = false;
m_CurrentEvent = String.Empty;
@@ -720,7 +740,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// This will be the very first event we deliver
// (state_entry) in default state
//
-
SaveState(m_Assembly);
m_SaveState = false;
--
cgit v1.1
From c386b68373d0f4c46811423a2ba9ffbb486a1d9f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 16 Mar 2012 01:31:53 +0000
Subject: Aggregate script execution times by linksets rather than individual
prims.
This is for the top scripts report.
---
OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index b177287..6e36742 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -164,6 +164,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public uint LocalID { get; private set; }
+ public UUID RootObjectID { get; private set; }
+
+ public uint RootLocalID { get; private set; }
+
public UUID AssetID { get; private set; }
public Queue EventQueue { get; private set; }
@@ -198,6 +202,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
Engine = engine;
LocalID = part.LocalId;
ObjectID = part.UUID;
+ RootLocalID = part.ParentGroup.LocalId;
+ RootObjectID = part.ParentGroup.UUID;
ItemID = itemID;
AssetID = assetID;
PrimName = primName;
--
cgit v1.1