XMR: there is no need for a slice thread, it also causes timing issues; BelowNormal mb 2 Below on win; cosmetics

httptests
UbitUmarov 2018-02-03 08:08:59 +00:00
parent 20ca517887
commit 04a8ec518d
6 changed files with 353 additions and 237 deletions

View File

@ -250,7 +250,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
} }
m_SleepThread = StartMyThread (RunSleepThread, "xmrengine sleep", ThreadPriority.Normal); m_SleepThread = StartMyThread (RunSleepThread, "xmrengine sleep", ThreadPriority.Normal);
m_SliceThread = StartMyThread (RunSliceThread, "xmrengine slice", ThreadPriority.Normal); // m_SliceThread = StartMyThread (RunSliceThread, "xmrengine slice", ThreadPriority.Normal);
/* /*
* Verify that our ScriptEventCode's match OpenSim's scriptEvent's. * Verify that our ScriptEventCode's match OpenSim's scriptEvent's.
@ -895,8 +895,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
m_log.Error("[XMREngine]: XMREngine.SaveAllState() called!!"); m_log.Error("[XMREngine]: XMREngine.SaveAllState() called!!");
} }
#pragma warning disable 0067
public event ScriptRemoved OnScriptRemoved; public event ScriptRemoved OnScriptRemoved;
public event ObjectRemoved OnObjectRemoved; public event ObjectRemoved OnObjectRemoved;
#pragma warning restore 0067
// Events targeted at a specific script // Events targeted at a specific script
// ... like listen() for an llListen() call // ... like listen() for an llListen() call

View File

@ -191,15 +191,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
newheapuse += dels.Length * HeapTrackerObject.HT_DELE; newheapuse += dels.Length * HeapTrackerObject.HT_DELE;
// lists, objects, strings are the sum of the size of each element // lists, objects, strings are the sum of the size of each element
foreach (LSL_List lis in liss) { foreach (LSL_List lis in liss)
newheapuse += HeapTrackerList.Size (lis); newheapuse += HeapTrackerList.Size (lis);
}
foreach (object obj in objs) { foreach (object obj in objs)
newheapuse += HeapTrackerObject.Size (obj); newheapuse += HeapTrackerObject.Size (obj);
}
foreach (string str in strs) { foreach (string str in strs)
newheapuse += HeapTrackerString.Size (str); newheapuse += HeapTrackerString.Size (str);
}
// others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage // others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage
@ -222,46 +221,55 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
int newheapuse = heapUse; int newheapuse = heapUse;
iarArrays = null; iarArrays = null;
if (iarChars != null) { if (iarChars != null)
{
newheapuse -= iarChars.Length * HeapTrackerObject.HT_CHAR; newheapuse -= iarChars.Length * HeapTrackerObject.HT_CHAR;
iarChars = null; iarChars = null;
} }
if (iarFloats != null) { if (iarFloats != null)
{
newheapuse -= iarFloats.Length * HeapTrackerObject.HT_SFLT; newheapuse -= iarFloats.Length * HeapTrackerObject.HT_SFLT;
iarFloats = null; iarFloats = null;
} }
if (iarIntegers != null) { if (iarIntegers != null)
{
newheapuse -= iarIntegers.Length * HeapTrackerObject.HT_INT; newheapuse -= iarIntegers.Length * HeapTrackerObject.HT_INT;
iarIntegers = null; iarIntegers = null;
} }
if (iarLists != null) { if (iarLists != null)
foreach (LSL_List lis in iarLists) { {
foreach (LSL_List lis in iarLists)
newheapuse -= HeapTrackerList.Size (lis); newheapuse -= HeapTrackerList.Size (lis);
}
iarLists = null; iarLists = null;
} }
if (iarObjects != null) { if (iarObjects != null)
foreach (object obj in iarObjects) { {
foreach (object obj in iarObjects)
newheapuse -= HeapTrackerObject.Size (obj); newheapuse -= HeapTrackerObject.Size (obj);
}
iarObjects = null; iarObjects = null;
} }
if (iarRotations != null) { if (iarRotations != null)
{
newheapuse -= iarRotations.Length * HeapTrackerObject.HT_ROT; newheapuse -= iarRotations.Length * HeapTrackerObject.HT_ROT;
iarRotations = null; iarRotations = null;
} }
if (iarStrings != null) { if (iarStrings != null)
foreach (string str in iarStrings) { {
foreach (string str in iarStrings)
newheapuse -= HeapTrackerString.Size (str); newheapuse -= HeapTrackerString.Size (str);
}
iarStrings = null; iarStrings = null;
} }
if (iarVectors != null) { if (iarVectors != null)
{
newheapuse -= iarVectors.Length * HeapTrackerObject.HT_VEC; newheapuse -= iarVectors.Length * HeapTrackerObject.HT_VEC;
iarVectors = null; iarVectors = null;
} }
iarSDTClObjs = null; iarSDTClObjs = null;
if (iarSDTIntfObjs != null) { if (iarSDTIntfObjs != null)
{
newheapuse -= iarSDTIntfObjs.Length * HeapTrackerObject.HT_DELE; newheapuse -= iarSDTIntfObjs.Length * HeapTrackerObject.HT_DELE;
iarSDTIntfObjs = null; iarSDTIntfObjs = null;
} }
@ -270,7 +278,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
} }
} }
public class XMRInstArSizes { public class XMRInstArSizes
{
public int iasArrays; public int iasArrays;
public int iasChars; public int iasChars;
public int iasFloats; public int iasFloats;
@ -327,7 +336,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
} }
} }
public class XMRStackFrame { public class XMRStackFrame
{
public XMRStackFrame nextSF; public XMRStackFrame nextSF;
public string funcName; public string funcName;
public int callNo; public int callNo;
@ -478,8 +488,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL : callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL :
XMRInstAbstract.CallMode_RESTORE; XMRInstAbstract.CallMode_RESTORE;
while (true) { while (true)
if (this.newStateCode < 0) { {
if (this.newStateCode < 0)
{
/* /*
* Process event given by 'stateCode' and 'eventCode'. * Process event given by 'stateCode' and 'eventCode'.
@ -487,10 +499,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
int newState = this.stateCode; int newState = this.stateCode;
seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode]; seh = this.m_ObjCode.scriptEventHandlerTable[newState,(int)this.eventCode];
if (seh != null) { if (seh != null)
try { {
try
{
seh (this); seh (this);
} catch (ScriptChangeStateException scse) { }
catch (ScriptChangeStateException scse)
{
newState = scse.newState; newState = scse.newState;
} }
} }
@ -503,7 +519,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* It does not execute the state_exit() or state_entry() handlers. * It does not execute the state_exit() or state_entry() handlers.
* See http://wiki.secondlife.com/wiki/State * See http://wiki.secondlife.com/wiki/State
*/ */
if (newState == this.stateCode) break; if (newState == this.stateCode)
break;
/* /*
* Save new state in a more permanent location in case we * Save new state in a more permanent location in case we
@ -517,10 +534,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
this.eventCode = ScriptEventCode.state_exit; this.eventCode = ScriptEventCode.state_exit;
seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit]; seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)ScriptEventCode.state_exit];
if (seh != null) { if (seh != null)
try { {
try
{
seh (this); seh (this);
} catch (ScriptChangeStateException scse) { }
catch (ScriptChangeStateException scse)
{
this.newStateCode = scse.newState; this.newStateCode = scse.newState;
} }
} }
@ -563,7 +584,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
public void CheckRunStack () public void CheckRunStack ()
{ {
if (xmrStackLeft () < stackLimit) { if (xmrStackLeft () < stackLimit)
{
throw new OutOfStackException (); throw new OutOfStackException ();
} }
CheckRunQuick (); CheckRunQuick ();
@ -574,9 +596,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
public void CheckRunQuick () public void CheckRunQuick ()
{ {
if (suspendOnCheckRunHold || suspendOnCheckRunTemp) { // if (suspendOnCheckRunHold || suspendOnCheckRunTemp) {
CheckRunWork (); CheckRunWork ();
} // }
} }
/** /**
@ -608,7 +630,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
public object[] RestoreStackFrame (string funcName, out int callNo) public object[] RestoreStackFrame (string funcName, out int callNo)
{ {
XMRStackFrame sf = stackFrames; XMRStackFrame sf = stackFrames;
if (sf.funcName != funcName) { if (sf.funcName != funcName)
{
throw new Exception ("frame mismatch " + sf.funcName + " vs " + funcName); throw new Exception ("frame mismatch " + sf.funcName + " vs " + funcName);
} }
callNo = sf.callNo; callNo = sf.callNo;
@ -625,7 +648,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
object[] oldarray = oldlist.Data; object[] oldarray = oldlist.Data;
int len = oldarray.Length; int len = oldarray.Length;
object[] newarray = new object[len]; object[] newarray = new object[len];
for (int i = 0; i < len; i ++) { for (int i = 0; i < len; i ++)
{
object obj = oldarray[i]; object obj = oldarray[i];
if (obj is LSL_Integer) obj = (int)(LSL_Integer)obj; if (obj is LSL_Integer) obj = (int)(LSL_Integer)obj;
newarray[i] = obj; newarray[i] = obj;
@ -643,18 +667,25 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
int len = oldarray.Length; int len = oldarray.Length;
object[] newarray = new object[len]; object[] newarray = new object[len];
int verbatim = 0; int verbatim = 0;
for (int i = 0; i < len; i ++) { for (int i = 0; i < len; i ++)
{
object obj = oldarray[i]; object obj = oldarray[i];
if (-- verbatim < 0) { if (-- verbatim < 0)
if (obj is LSL_Integer) obj = (int)(LSL_Integer)obj; {
if (obj is int) { if (obj is LSL_Integer)
switch ((int)obj) { obj = (int)(LSL_Integer)obj;
case ScriptBaseClass.PARCEL_MEDIA_COMMAND_AUTO_ALIGN: { if (obj is int)
{
switch ((int)obj)
{
case ScriptBaseClass.PARCEL_MEDIA_COMMAND_AUTO_ALIGN:
{
// leave next integer as LSL_Integer // leave next integer as LSL_Integer
verbatim = 1; verbatim = 1;
break; break;
} }
case ScriptBaseClass.PARCEL_MEDIA_COMMAND_SIZE: { case ScriptBaseClass.PARCEL_MEDIA_COMMAND_SIZE:
{
// leave next two integers as LSL_Integer // leave next two integers as LSL_Integer
verbatim = 2; verbatim = 2;
break; break;
@ -715,7 +746,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* class that is implementing the interface. This should let the next * class that is implementing the interface. This should let the next
* step get the script-defined type name of the object. * step get the script-defined type name of the object.
*/ */
if (o is Delegate[]) { if (o is Delegate[])
{
o = ((Delegate[])o)[0].Target; o = ((Delegate[])o)[0].Target;
} }
@ -723,7 +755,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* If script-defined class instance, get the script-defined * If script-defined class instance, get the script-defined
* type name. * type name.
*/ */
if (o is XMRSDTypeClObj) { if (o is XMRSDTypeClObj)
{
return ((XMRSDTypeClObj)o).sdtcClass.longName.val; return ((XMRSDTypeClObj)o).sdtcClass.longName.val;
} }
@ -731,7 +764,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* If it's a delegate, maybe we can look up its script-defined type name. * If it's a delegate, maybe we can look up its script-defined type name.
*/ */
Type ot = o.GetType (); Type ot = o.GetType ();
if (o is Delegate) { if (o is Delegate)
{
String os; String os;
if (m_ObjCode.sdDelTypes.TryGetValue (ot, out os)) return os; if (m_ObjCode.sdDelTypes.TryGetValue (ot, out os)) return os;
} }
@ -754,7 +788,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
object[] data = ev.Data; object[] data = ev.Data;
int evc = (int)(ev.GetLSLIntegerItem (0).value & 0xFFFFFFFF); int evc = (int)(ev.GetLSLIntegerItem (0).value & 0xFFFFFFFF);
ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode,evc]; ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode,evc];
if (seh != null) { if (seh != null)
{
int nargs = data.Length - 1; int nargs = data.Length - 1;
object[] args = new object[nargs]; object[] args = new object[nargs];
Array.Copy (data, 1, args, 0, nargs); Array.Copy (data, 1, args, 0, nargs);
@ -777,23 +812,30 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
public string xmrSubstring (string s, int offset) public string xmrSubstring (string s, int offset)
{ {
if (offset >= s.Length) return ""; if (offset >= s.Length)
return "";
return s.Substring (offset); return s.Substring (offset);
} }
// C# style // C# style
public string xmrSubstring (string s, int offset, int length) public string xmrSubstring (string s, int offset, int length)
{ {
if (length <= 0) return ""; if (length <= 0)
if (offset >= s.Length) return ""; return "";
if (length > s.Length - offset) length = s.Length - offset; if (offset >= s.Length)
return "";
if (length > s.Length - offset)
length = s.Length - offset;
return s.Substring (offset, length); return s.Substring (offset, length);
} }
// java style // java style
public string xmrJSubstring (string s, int beg, int end) public string xmrJSubstring (string s, int beg, int end)
{ {
if (end <= beg) return ""; if (end <= beg)
if (beg >= s.Length) return ""; return "";
if (end > s.Length) end = s.Length; if (beg >= s.Length)
return "";
if (end > s.Length)
end = s.Length;
return s.Substring (beg, end - beg); return s.Substring (beg, end - beg);
} }
@ -839,22 +881,22 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
public int xmrString2Integer (string s) public int xmrString2Integer (string s)
{ {
s = s.Trim (); s = s.Trim ();
if (s.StartsWith ("0x") || s.StartsWith ("0X")) { if (s.StartsWith ("0x") || s.StartsWith ("0X"))
return int.Parse (s.Substring (2), NumberStyles.HexNumber); return int.Parse (s.Substring (2), NumberStyles.HexNumber);
}
return int.Parse (s, CultureInfo.InvariantCulture); return int.Parse (s, CultureInfo.InvariantCulture);
} }
public LSL_Rotation xmrString2Rotation (string s) public LSL_Rotation xmrString2Rotation (string s)
{ {
s = s.Trim (); s = s.Trim ();
if (!s.StartsWith ("<") || !s.EndsWith (">")) { if (!s.StartsWith ("<") || !s.EndsWith (">"))
throw new FormatException ("doesn't begin with < and end with >"); throw new FormatException ("doesn't begin with < and end with >");
}
s = s.Substring (1, s.Length - 2); s = s.Substring (1, s.Length - 2);
string[] splitup = s.Split (justacomma, 5); string[] splitup = s.Split (justacomma, 5);
if (splitup.Length != 4) { if (splitup.Length != 4)
throw new FormatException ("doesn't have exactly 3 commas"); throw new FormatException ("doesn't have exactly 3 commas");
}
double x = double.Parse (splitup[0], CultureInfo.InvariantCulture); double x = double.Parse (splitup[0], CultureInfo.InvariantCulture);
double y = double.Parse (splitup[1], CultureInfo.InvariantCulture); double y = double.Parse (splitup[1], CultureInfo.InvariantCulture);
double z = double.Parse (splitup[2], CultureInfo.InvariantCulture); double z = double.Parse (splitup[2], CultureInfo.InvariantCulture);
@ -864,14 +906,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
public LSL_Vector xmrString2Vector (string s) public LSL_Vector xmrString2Vector (string s)
{ {
s = s.Trim (); s = s.Trim ();
if (!s.StartsWith ("<") || !s.EndsWith (">")) { if (!s.StartsWith ("<") || !s.EndsWith (">"))
throw new FormatException ("doesn't begin with < and end with >"); throw new FormatException ("doesn't begin with < and end with >");
}
s = s.Substring (1, s.Length - 2); s = s.Substring (1, s.Length - 2);
string[] splitup = s.Split (justacomma, 4); string[] splitup = s.Split (justacomma, 4);
if (splitup.Length != 3) { if (splitup.Length != 3)
throw new FormatException ("doesn't have exactly 2 commas"); throw new FormatException ("doesn't have exactly 2 commas");
}
double x = double.Parse (splitup[0], CultureInfo.InvariantCulture); double x = double.Parse (splitup[0], CultureInfo.InvariantCulture);
double y = double.Parse (splitup[1], CultureInfo.InvariantCulture); double y = double.Parse (splitup[1], CultureInfo.InvariantCulture);
double z = double.Parse (splitup[2], CultureInfo.InvariantCulture); double z = double.Parse (splitup[2], CultureInfo.InvariantCulture);
@ -933,14 +975,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
/* /*
* If it is a script-defined interface object, convert to the original XMRSDTypeClObj. * If it is a script-defined interface object, convert to the original XMRSDTypeClObj.
*/ */
if (thrown is Delegate[]) { if (thrown is Delegate[])
thrown = ((Delegate[])thrown)[0].Target; thrown = ((Delegate[])thrown)[0].Target;
}
/* /*
* If it is a script-defined delegate object, make sure it is an instance of the expected type. * If it is a script-defined delegate object, make sure it is an instance of the expected type.
*/ */
if (thrown is Delegate) { if (thrown is Delegate)
{
Type ot = thrown.GetType (); Type ot = thrown.GetType ();
Type tt = sdType.GetSysType (); Type tt = sdType.GetSysType ();
return (ot == tt) ? thrown : null; return (ot == tt) ? thrown : null;
@ -949,15 +991,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
/* /*
* If it is a script-defined class object, make sure it is an instance of the expected class. * If it is a script-defined class object, make sure it is an instance of the expected class.
*/ */
if (thrown is XMRSDTypeClObj) { if (thrown is XMRSDTypeClObj)
{
/* /*
* Step from the object's actual class rootward. * Step from the object's actual class rootward.
* If we find the requested class along the way, the cast is valid. * If we find the requested class along the way, the cast is valid.
* If we run off the end of the root, the cast is not valid. * If we run off the end of the root, the cast is not valid.
*/ */
for (TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends) { for (TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends)
if (ac == sdType) return thrown; {
if (ac == sdType)
return thrown;
} }
} }
@ -1015,10 +1060,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
int i = srctypename.IndexOf ('['); int i = srctypename.IndexOf ('[');
int j = dsttypename.IndexOf ('['); int j = dsttypename.IndexOf ('[');
if ((i < 0) || (j < 0)) throw new InvalidCastException ("non-array passed: " + srctypename + " and/or " + dsttypename); if ((i < 0) || (j < 0))
if ((i != j) || !srctypename.StartsWith (dsttypename.Substring (0, j))) { throw new InvalidCastException ("non-array passed: " + srctypename + " and/or " + dsttypename);
if ((i != j) || !srctypename.StartsWith (dsttypename.Substring (0, j)))
throw new ArrayTypeMismatchException (srctypename + " vs " + dsttypename); throw new ArrayTypeMismatchException (srctypename + " vs " + dsttypename);
}
/* /*
* The number of brackets must match exactly. * The number of brackets must match exactly.
@ -1030,11 +1076,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
int dstlen = dsttypename.Length; int dstlen = dsttypename.Length;
int srcjags = 0; int srcjags = 0;
int dstjags = 0; int dstjags = 0;
while (++ i < srclen) if (srctypename[i] == ']') srcjags ++; while (++ i < srclen)
while (++ j < dstlen) if (dsttypename[j] == ']') dstjags ++; if (srctypename[i] == ']')
if (dstjags != srcjags) { srcjags ++;
while (++ j < dstlen)
if (dsttypename[j] == ']')
dstjags ++;
if (dstjags != srcjags)
throw new ArrayTypeMismatchException (srctypename + " vs " + dsttypename); throw new ArrayTypeMismatchException (srctypename + " vs " + dsttypename);
}
/* /*
* Perform the copy. * Perform the copy.
@ -1059,9 +1109,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
TokenDeclSDTypeClass sdtClass = array.sdtcClass; TokenDeclSDTypeClass sdtClass = array.sdtcClass;
if (sdtClass.arrayOfRank == 0) { if (sdtClass.arrayOfRank == 0)
throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val);
}
/* /*
* Validate objects they want to put in the list. * Validate objects they want to put in the list.
@ -1069,26 +1119,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
Array srcarray = (Array)array.instVars.iarObjects[0]; Array srcarray = (Array)array.instVars.iarObjects[0];
object[] output = new object[count]; object[] output = new object[count];
for (int i = 0; i < count; i ++) { for (int i = 0; i < count; i ++)
{
object src = srcarray.GetValue (i + start); object src = srcarray.GetValue (i + start);
if (src == null) throw new NullReferenceException ("null element " + i); if (src == null)
if (src is double) { throw new NullReferenceException ("null element " + i);
if (src is double)
{
output[i] = new LSL_Float ((double)src); output[i] = new LSL_Float ((double)src);
continue; continue;
} }
if (src is int) { if (src is int)
{
output[i] = new LSL_Integer ((int)src); output[i] = new LSL_Integer ((int)src);
continue; continue;
} }
if (src is LSL_Rotation) { if (src is LSL_Rotation)
{
output[i] = src; output[i] = src;
continue; continue;
} }
if (src is LSL_Vector) { if (src is LSL_Vector)
{
output[i] = src; output[i] = src;
continue; continue;
} }
if (src is string) { if (src is string)
{
output[i] = new LSL_String ((string)src); output[i] = new LSL_String ((string)src);
continue; continue;
} }
@ -1117,9 +1174,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
if (sdtClass.arrayOfType == null) { if (sdtClass.arrayOfType == null)
throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val);
}
/* /*
* Copy from the immutable array to the mutable array. * Copy from the immutable array to the mutable array.
@ -1128,11 +1184,12 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
object[] srcarr = srclist.Data; object[] srcarr = srclist.Data;
Array dstarr = (Array)dstarray.instVars.iarObjects[0]; Array dstarr = (Array)dstarray.instVars.iarObjects[0];
for (int i = 0; i < count; i ++) { for (int i = 0; i < count; i ++)
{
object obj = srcarr[i+srcstart]; object obj = srcarr[i+srcstart];
if (obj is LSL_Float) obj = ((LSL_Float)obj).value; if (obj is LSL_Float) obj = ((LSL_Float)obj).value;
if (obj is LSL_Integer) obj = ((LSL_Integer)obj).value; else if (obj is LSL_Integer) obj = ((LSL_Integer)obj).value;
if (obj is LSL_String) obj = ((LSL_String)obj).m_string; else if (obj is LSL_String) obj = ((LSL_String)obj).m_string;
dstarr.SetValue (obj, i + dststart); dstarr.SetValue (obj, i + dststart);
} }
} }
@ -1151,9 +1208,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
TokenDeclSDTypeClass sdtClass = array.sdtcClass; TokenDeclSDTypeClass sdtClass = array.sdtcClass;
if (sdtClass.arrayOfRank == 0) { if (sdtClass.arrayOfRank == 0)
throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val);
}
/* /*
* We get a type cast error from mono if they didn't give us a character array. * We get a type cast error from mono if they didn't give us a character array.
@ -1178,19 +1234,17 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
if (sdtClass.arrayOfType == null) { if (sdtClass.arrayOfType == null)
throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val); throw new InvalidCastException ("only do arrays not " + sdtClass.longName.val);
}
/* /*
* We get a type cast error from mono if they didn't give us a character array. * We get a type cast error from mono if they didn't give us a character array.
* But if it is ok, copy from the string to the character array. * But if it is ok, copy from the string to the character array.
*/ */
char[] dstarr = (char[])dstarray.instVars.iarObjects[0]; char[] dstarr = (char[])dstarray.instVars.iarObjects[0];
for (int i = 0; i < count; i ++) { for (int i = 0; i < count; i ++)
dstarr[i+dststart] = srcstr[i+srcstart]; dstarr[i+dststart] = srcstr[i+srcstart];
} }
}
/** /**
* @brief Implement osParseJSON() so we return an array to the script. * @brief Implement osParseJSON() so we return an array to the script.
@ -1202,8 +1256,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
{ {
XMR_Array dict = new XMR_Array (this); XMR_Array dict = new XMR_Array (this);
int idx = ParseJSON (dict, nullList, json, 0); int idx = ParseJSON (dict, nullList, json, 0);
while (idx < json.Length) { while (idx < json.Length)
if (json[idx] > ' ') throw new Exception ("left-over json " + json); {
if (json[idx] > ' ')
throw new Exception ("left-over json " + json);
idx ++; idx ++;
} }
return dict; return dict;
@ -1214,35 +1270,46 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
char c; char c;
while ((c = json[idx++]) <= ' ') { } while ((c = json[idx++]) <= ' ') { }
switch (c) { switch (c)
{
// '{' <keystring> ':' <value> [ ',' <keystring> ':' <value> ... ] '}' // '{' <keystring> ':' <value> [ ',' <keystring> ':' <value> ... ] '}'
case '{': { case '{':
do { {
do
{
string key = ParseJSONString (json, ref idx); string key = ParseJSONString (json, ref idx);
while ((c = json[idx++]) <= ' ') { } while ((c = json[idx++]) <= ' ') { }
if (c != ':') throw new Exception ("missing : after key"); if (c != ':')
throw new Exception ("missing : after key");
idx = ParseJSON (dict, ParseJSONKeyAdd (keys, key), json, idx); idx = ParseJSON (dict, ParseJSONKeyAdd (keys, key), json, idx);
while ((c = json[idx++]) <= ' ') { } while ((c = json[idx++]) <= ' ') { }
} while (c == ','); } while (c == ',');
if (c != '}') throw new Exception ("missing , or } after value");
if (c != '}')
throw new Exception ("missing , or } after value");
break; break;
} }
// '[' <value> [ ',' <value> ... ] ']' // '[' <value> [ ',' <value> ... ] ']'
case '[': { case '[':
{
int index = 0; int index = 0;
do { do
{
object key = index ++; object key = index ++;
idx = ParseJSON (dict, ParseJSONKeyAdd (keys, key), json, idx); idx = ParseJSON (dict, ParseJSONKeyAdd (keys, key), json, idx);
while ((c = json[idx++]) <= ' ') { } while ((c = json[idx++]) <= ' ') { }
} while (c == ','); } while (c == ',');
if (c != ']') throw new Exception ("missing , or ] after value");
if (c != ']')
throw new Exception ("missing , or ] after value");
break; break;
} }
// '"'<string>'"' // '"'<string>'"'
case '"': { case '"':
{
-- idx; -- idx;
string val = ParseJSONString (json, ref idx); string val = ParseJSONString (json, ref idx);
dict.SetByKey (keys, val); dict.SetByKey (keys, val);
@ -1250,29 +1317,36 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
} }
// true false null // true false null
case 't': { case 't':
if (json.Substring (idx, 3) != "rue") throw new Exception ("bad true in json"); {
if (json.Substring (idx, 3) != "rue")
throw new Exception ("bad true in json");
idx += 3; idx += 3;
dict.SetByKey (keys, 1); dict.SetByKey (keys, 1);
break; break;
} }
case 'f': { case 'f':
if (json.Substring (idx, 4) != "alse") throw new Exception ("bad false in json"); {
if (json.Substring (idx, 4) != "alse")
throw new Exception ("bad false in json");
idx += 4; idx += 4;
dict.SetByKey (keys, 0); dict.SetByKey (keys, 0);
break; break;
} }
case 'n': { case 'n':
if (json.Substring (idx, 3) != "ull") throw new Exception ("bad null in json"); {
if (json.Substring (idx, 3) != "ull")
throw new Exception ("bad null in json");
idx += 3; idx += 3;
dict.SetByKey (keys, null); dict.SetByKey (keys, null);
break; break;
} }
// otherwise assume it's a number // otherwise assume it's a number
default: { default:
{
-- idx; -- idx;
object val = ParseJSONNumber (json, ref idx); object val = ParseJSONNumber (json, ref idx);
dict.SetByKey (keys, val); dict.SetByKey (keys, val);
@ -1302,36 +1376,39 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
if (c != '"') throw new Exception ("bad start of json string"); if (c != '"') throw new Exception ("bad start of json string");
StringBuilder sb = new StringBuilder (); StringBuilder sb = new StringBuilder ();
while ((c = json[idx++]) != '"') { while ((c = json[idx++]) != '"')
if (c == '\\') { {
if (c == '\\')
{
c = json[idx++]; c = json[idx++];
switch (c) { switch (c)
case 'b': { {
case 'b':
c = '\b'; c = '\b';
break; break;
}
case 'f': { case 'f':
c = '\f'; c = '\f';
break; break;
}
case 'n': { case 'n':
c = '\n'; c = '\n';
break; break;
}
case 'r': { case 'r':
c = '\r'; c = '\r';
break; break;
}
case 't': { case 't':
c = '\t'; c = '\t';
break; break;
}
case 'u': { case 'u':
c = (char) Int32.Parse (json.Substring (idx, 4), c = (char) Int32.Parse (json.Substring (idx, 4),
System.Globalization.NumberStyles.HexNumber); System.Globalization.NumberStyles.HexNumber);
idx += 4; idx += 4;
break; break;
}
default: break; default: break;
} }
} }
@ -1358,49 +1435,65 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
isneg = true; isneg = true;
c = json[idx++]; c = json[idx++];
} }
if ((c < '0') || (c > '9')) { if ((c < '0') || (c > '9'))
throw new Exception ("bad json number"); throw new Exception ("bad json number");
}
while ((c >= '0') && (c <= '9')) { while ((c >= '0') && (c <= '9'))
{
dval *= 10; dval *= 10;
ival *= 10; ival *= 10;
dval += c - '0'; dval += c - '0';
ival += c - '0'; ival += c - '0';
c = '\0'; c = '\0';
if (idx < json.Length) c = json[idx++]; if (idx < json.Length)
c = json[idx++];
} }
if (c == '.') { if (c == '.')
{
decpt = 0; decpt = 0;
c = '\0'; c = '\0';
if (idx < json.Length) c = json[idx++]; if (idx < json.Length)
c = json[idx++];
while ((c >= '0') && (c <= '9')) { while ((c >= '0') && (c <= '9')) {
dval *= 10; dval *= 10;
dval += c - '0'; dval += c - '0';
decpt ++; decpt ++;
c = '\0'; c = '\0';
if (idx < json.Length) c = json[idx++]; if (idx < json.Length)
}
}
if ((c == 'e') || (c == 'E')) {
if (decpt < 0) decpt = 0;
c = json[idx++]; c = json[idx++];
if (c == '-') expneg = true; }
if ((c == '-') || (c == '+')) c = json[idx++]; }
while ((c >= '0') && (c <= '9')) { if ((c == 'e') || (c == 'E'))
{
if (decpt < 0)
decpt = 0;
c = json[idx++];
if (c == '-')
expneg = true;
if ((c == '-') || (c == '+'))
c = json[idx++];
while ((c >= '0') && (c <= '9'))
{
expon *= 10; expon *= 10;
expon += c - '0'; expon += c - '0';
c = '\0'; c = '\0';
if (idx < json.Length) c = json[idx++]; if (idx < json.Length)
c = json[idx++];
} }
if (expneg) expon = -expon; if (expneg)
expon = -expon;
} }
if (c != 0) -- idx; if (c != 0)
if (decpt < 0) { --idx;
if (isneg) ival = -ival; if (decpt < 0)
{
if (isneg)
ival = -ival;
return ival; return ival;
} else { } else {
if (isneg) dval = -dval; if (isneg)
dval = -dval;
dval *= Math.Pow (10, expon - decpt); dval *= Math.Pow (10, expon - decpt);
return dval; return dval;
} }

View File

@ -27,17 +27,9 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Reflection;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.Remoting.Lifetime;
using System.Security.Policy;
using System.IO;
using System.Xml;
using System.Text;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api; using OpenSim.Region.ScriptEngine.Shared.Api;
using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
@ -331,7 +323,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
ScriptEventCode evc = ScriptEventCode.None; ScriptEventCode evc = ScriptEventCode.None;
callNo = -1; callNo = -1;
try { try
{
if (callMode == CallMode_NORMAL) goto findevent; if (callMode == CallMode_NORMAL) goto findevent;
/* /*
@ -344,9 +337,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
returnMask2 = (int)sv[2]; returnMask2 = (int)sv[2];
mask1 = (int)sv[3]; mask1 = (int)sv[3];
mask2 = (int)sv[4]; mask2 = (int)sv[4];
switch (callNo) { switch (callNo)
{
case 0: goto __call0; case 0: goto __call0;
case 1: { case 1:
{
evc1 = (int)sv[5]; evc1 = (int)sv[5];
evc = (ScriptEventCode)(int)sv[6]; evc = (ScriptEventCode)(int)sv[6];
DetectParams[] detprms = ObjArrToDetPrms ((object[])sv[7]); DetectParams[] detprms = ObjArrToDetPrms ((object[])sv[7]);
@ -362,13 +357,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
findevent: findevent:
Monitor.Enter (m_QueueLock); Monitor.Enter (m_QueueLock);
for (lln = m_EventQueue.First; lln != null; lln = lln.Next) { for (lln = m_EventQueue.First; lln != null; lln = lln.Next)
{
evt = lln.Value; evt = lln.Value;
evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), evt.EventName); evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), evt.EventName);
evc1 = (int)evc; evc1 = (int)evc;
evc2 = evc1 - 32; evc2 = evc1 - 32;
if ((((uint)evc1 < (uint)32) && (((mask1 >> evc1) & 1) != 0)) || if ((((uint)evc1 < (uint)32) && (((mask1 >> evc1) & 1) != 0)) ||
(((uint)evc2 < (uint)32) && (((mask2 >> evc2) & 1) != 0))) goto remfromq; (((uint)evc2 < (uint)32) && (((mask2 >> evc2) & 1) != 0)))
goto remfromq;
} }
/* /*
@ -389,9 +386,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
remfromq: remfromq:
m_EventQueue.Remove (lln); m_EventQueue.Remove (lln);
if ((uint)evc1 < (uint)m_EventCounts.Length) { if ((uint)evc1 < (uint)m_EventCounts.Length)
m_EventCounts[evc1] --; m_EventCounts[evc1] --;
}
Monitor.Exit (m_QueueLock); Monitor.Exit (m_QueueLock);
m_InstEHEvent ++; m_InstEHEvent ++;
@ -399,7 +396,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* See if returnable or background event. * See if returnable or background event.
*/ */
if ((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) || if ((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) ||
(((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0))) { (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0)))
{
/* /*
* Returnable event, return its parameters in a list. * Returnable event, return its parameters in a list.
@ -408,11 +406,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
int plen = evt.Params.Length; int plen = evt.Params.Length;
object[] plist = new object[plen+1]; object[] plist = new object[plen+1];
plist[0] = (LSL_Integer)evc1; plist[0] = (LSL_Integer)evc1;
for (int i = 0; i < plen;) { for (int i = 0; i < plen;)
{
object ob = evt.Params[i]; object ob = evt.Params[i];
if (ob is int) ob = (LSL_Integer)(int)ob; if (ob is int)
else if (ob is double) ob = (LSL_Float)(double)ob; ob = (LSL_Integer)(int)ob;
else if (ob is string) ob = (LSL_String)(string)ob; else if (ob is double)
ob = (LSL_Float)(double)ob;
else if (ob is string)
ob = (LSL_String)(string)ob;
plist[++i] = ob; plist[++i] = ob;
} }
m_DetectParams = evt.DetectParams; m_DetectParams = evt.DetectParams;
@ -426,7 +428,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
callNo = 1; callNo = 1;
__call1: __call1:
ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode,evc1]; ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode,evc1];
if (seh == null) goto checktmo; if (seh == null)
goto checktmo;
DetectParams[] saveDetParams = this.m_DetectParams; DetectParams[] saveDetParams = this.m_DetectParams;
object[] saveEHArgs = this.ehArgs; object[] saveEHArgs = this.ehArgs;
@ -436,26 +439,33 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
this.ehArgs = evt.Params; this.ehArgs = evt.Params;
this.eventCode = evc; this.eventCode = evc;
try { try
{
seh (this); seh (this);
} finally { }
this.m_DetectParams = saveDetParams; finally
this.ehArgs = saveEHArgs; {
this.eventCode = saveEventCode; m_DetectParams = saveDetParams;
ehArgs = saveEHArgs;
eventCode = saveEventCode;
} }
/* /*
* Keep waiting until we find a returnable event or timeout. * Keep waiting until we find a returnable event or timeout.
*/ */
checktmo: checktmo:
if (DateTime.UtcNow < sleepUntil) goto findevent; if (DateTime.UtcNow < sleepUntil)
goto findevent;
/* /*
* We timed out, return an empty list. * We timed out, return an empty list.
*/ */
return emptyList; return emptyList;
} finally { }
if (callMode != CallMode_NORMAL) { finally
{
if (callMode != CallMode_NORMAL)
{
/* /*
* Stack frame is being saved by CheckRun...(). * Stack frame is being saved by CheckRun...().
@ -468,7 +478,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
sv[2] = returnMask2; // needed at __call0,__call1 sv[2] = returnMask2; // needed at __call0,__call1
sv[3] = mask1; // needed at __call0,__call1 sv[3] = mask1; // needed at __call0,__call1
sv[4] = mask2; // needed at __call0,__call1 sv[4] = mask2; // needed at __call0,__call1
if (callNo == 1) { if (callNo == 1)
{
sv[5] = evc1; // needed at __call1 sv[5] = evc1; // needed at __call1
sv[6] = (int)evc; // needed at __call1 sv[6] = (int)evc; // needed at __call1
sv[7] = DetPrmsToObjArr (evt.DetectParams); // needed at __call1 sv[7] = DetPrmsToObjArr (evt.DetectParams); // needed at __call1
@ -515,7 +526,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
object[] obs = new object[len*16+1]; object[] obs = new object[len*16+1];
int j = 0; int j = 0;
obs[j++] = (LSL_Integer)saveDPVer; obs[j++] = (LSL_Integer)saveDPVer;
for (int i = 0; i < len; i ++) { for (int i = 0; i < len; i ++)
{
DetectParams dp = dps[i]; DetectParams dp = dps[i];
obs[j++] = (LSL_String)dp.Key.ToString(); // UUID obs[j++] = (LSL_String)dp.Key.ToString(); // UUID
obs[j++] = dp.OffsetPos; // vector obs[j++] = dp.OffsetPos; // vector
@ -550,14 +562,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
private static DetectParams[] ObjArrToDetPrms (object[] objs) private static DetectParams[] ObjArrToDetPrms (object[] objs)
{ {
int j = 0; int j = 0;
if ((objs.Length % 16 != 1) || (ListInt (objs[j++]) != saveDPVer)) { if ((objs.Length % 16 != 1) || (ListInt (objs[j++]) != saveDPVer))
throw new Exception ("invalid detect param format"); throw new Exception ("invalid detect param format");
}
int len = objs.Length / 16; int len = objs.Length / 16;
DetectParams[] dps = new DetectParams[len]; DetectParams[] dps = new DetectParams[len];
for (int i = 0; i < len; i ++) { for (int i = 0; i < len; i ++)
{
DetectParams dp = new DetectParams (); DetectParams dp = new DetectParams ();
dp.Key = new UUID (ListStr (objs[j++])); dp.Key = new UUID (ListStr (objs[j++]));
@ -612,9 +624,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
/* /*
* Clear out any old events from the queue. * Clear out any old events from the queue.
*/ */
lock (m_QueueLock) { lock (m_QueueLock)
{
m_EventQueue.Clear(); m_EventQueue.Clear();
for (int i = m_EventCounts.Length; -- i >= 0;) m_EventCounts[i] = 0; for (int i = m_EventCounts.Length; -- i >= 0;)
m_EventCounts[i] = 0;
} }
} }

View File

@ -140,6 +140,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
public int m_InstEHEvent = 0; // number of events dequeued (StartEventHandler called) public int m_InstEHEvent = 0; // number of events dequeued (StartEventHandler called)
public int m_InstEHSlice = 0; // number of times handler timesliced (ResumeEx called) public int m_InstEHSlice = 0; // number of times handler timesliced (ResumeEx called)
public double m_CPUTime = 0; // accumulated CPU time (milliseconds) public double m_CPUTime = 0; // accumulated CPU time (milliseconds)
public double m_SliceStart = 0; // when did current exec start
// If code needs to have both m_QueueLock and m_RunLock, // If code needs to have both m_QueueLock and m_RunLock,
// be sure to lock m_RunLock first then m_QueueLock, as // be sure to lock m_RunLock first then m_QueueLock, as

View File

@ -27,14 +27,7 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Reflection;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection.Emit;
using System.Runtime.Remoting.Lifetime;
using System.Security.Policy;
using System.IO;
using System.Xml;
using System.Text; using System.Text;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
@ -140,22 +133,23 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* of all others so the m_DetachQuantum won't run out * of all others so the m_DetachQuantum won't run out
* before attach(NULL_KEY) is executed. * before attach(NULL_KEY) is executed.
*/ */
case ScriptEventCode.attach: { case ScriptEventCode.attach:
{
if (evt.Params[0].ToString() == UUID.Zero.ToString()) if (evt.Params[0].ToString() == UUID.Zero.ToString())
{ {
LinkedListNode<EventParams> lln2 = null; LinkedListNode<EventParams> lln2 = null;
for (lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next) { for (lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next)
{
EventParams evt2 = lln2.Value; EventParams evt2 = lln2.Value;
ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode),
evt2.EventName); evt2.EventName);
if ((evc2 != ScriptEventCode.state_entry) && if ((evc2 != ScriptEventCode.state_entry) &&
(evc2 != ScriptEventCode.attach)) break; (evc2 != ScriptEventCode.attach)) break;
} }
if (lln2 == null) { if (lln2 == null)
m_EventQueue.AddLast(lln); m_EventQueue.AddLast(lln);
} else { else
m_EventQueue.AddBefore(lln2, lln); m_EventQueue.AddBefore(lln2, lln);
}
/* If we're detaching, limit the qantum. This will also /* If we're detaching, limit the qantum. This will also
* cause the script to self-suspend after running this * cause the script to self-suspend after running this
* event * event
@ -165,16 +159,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
m_DetachQuantum = 100; m_DetachQuantum = 100;
} }
else else
{
m_EventQueue.AddLast(lln); m_EventQueue.AddLast(lln);
}
break; break;
} }
/* /*
* All others just go on end in the order queued. * All others just go on end in the order queued.
*/ */
default: { default:
{
m_EventQueue.AddLast(lln); m_EventQueue.AddLast(lln);
break; break;
} }
@ -187,7 +180,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* to do the same thing right now. * to do the same thing right now.
* Dont' flag it if it's still suspended! * Dont' flag it if it's still suspended!
*/ */
if ((m_IState == XMRInstState.IDLE) && !m_Suspended) { if ((m_IState == XMRInstState.IDLE) && !m_Suspended)
{
m_IState = XMRInstState.ONSTARTQ; m_IState = XMRInstState.ONSTARTQ;
startIt = true; startIt = true;
} }
@ -196,11 +190,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* If instance is sleeping (ie, possibly in xmrEventDequeue), * If instance is sleeping (ie, possibly in xmrEventDequeue),
* wake it up if event is in the mask. * wake it up if event is in the mask.
*/ */
if ((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) { if ((m_SleepUntil > DateTime.UtcNow) && !m_Suspended)
{
int evc1 = (int)evc; int evc1 = (int)evc;
int evc2 = evc1 - 32; int evc2 = evc1 - 32;
if ((((uint)evc1 < (uint)32) && (((m_SleepEventMask1 >> evc1) & 1) != 0)) || if ((((uint)evc1 < (uint)32) && (((m_SleepEventMask1 >> evc1) & 1) != 0)) ||
(((uint)evc2 < (uint)32) && (((m_SleepEventMask2 >> evc2) & 1) != 0))) { (((uint)evc2 < (uint)32) && (((m_SleepEventMask2 >> evc2) & 1) != 0)))
{
wakeIt = true; wakeIt = true;
} }
} }
@ -210,14 +206,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* If transitioned from IDLE->ONSTARTQ, actually go insert it * If transitioned from IDLE->ONSTARTQ, actually go insert it
* on m_StartQueue and give the RunScriptThread() a wake-up. * on m_StartQueue and give the RunScriptThread() a wake-up.
*/ */
if (startIt) { if (startIt)
m_Engine.QueueToStart(this); m_Engine.QueueToStart(this);
}
/* /*
* Likewise, if the event mask triggered a wake, wake it up. * Likewise, if the event mask triggered a wake, wake it up.
*/ */
if (wakeIt) { if (wakeIt)
{
m_SleepUntil = DateTime.MinValue; m_SleepUntil = DateTime.MinValue;
m_Engine.WakeFromSleep(this); m_Engine.WakeFromSleep(this);
} }
@ -231,6 +227,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
public XMRInstState RunOne() public XMRInstState RunOne()
{ {
DateTime now = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
m_SliceStart = Util.GetTimeStampMS();
/* /*
* If script has called llSleep(), don't do any more until time is * If script has called llSleep(), don't do any more until time is
@ -247,7 +244,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* Also, someone may have called Suspend(). * Also, someone may have called Suspend().
*/ */
m_RunOnePhase = "check m_SuspendCount"; m_RunOnePhase = "check m_SuspendCount";
if (m_SuspendCount > 0) { if (m_SuspendCount > 0)
{
m_RunOnePhase = "return is suspended"; m_RunOnePhase = "return is suspended";
return XMRInstState.SUSPENDED; return XMRInstState.SUSPENDED;
} }
@ -258,7 +256,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* back right away, delay a bit so we don't get in infinite loop. * back right away, delay a bit so we don't get in infinite loop.
*/ */
m_RunOnePhase = "lock m_RunLock"; m_RunOnePhase = "lock m_RunLock";
if (!Monitor.TryEnter (m_RunLock)) { if (!Monitor.TryEnter (m_RunLock))
{
m_SleepUntil = now.AddMilliseconds(3); m_SleepUntil = now.AddMilliseconds(3);
m_RunOnePhase = "return was locked"; m_RunOnePhase = "return was locked";
return XMRInstState.ONSLEEPQ; return XMRInstState.ONSLEEPQ;
@ -282,7 +281,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
/* /*
* Do some more of the last event if it didn't finish. * Do some more of the last event if it didn't finish.
*/ */
else if (this.eventCode != ScriptEventCode.None) else if (eventCode != ScriptEventCode.None)
{ {
lock (m_QueueLock) lock (m_QueueLock)
{ {
@ -336,10 +335,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
if (m_EventQueue.First != null) if (m_EventQueue.First != null)
{ {
evt = m_EventQueue.First.Value; evt = m_EventQueue.First.Value;
if (m_DetachQuantum > 0)
{
evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode),
evt.EventName); evt.EventName);
if (m_DetachQuantum > 0)
{
if (evc != ScriptEventCode.attach) if (evc != ScriptEventCode.attach)
{ {
/* /*
@ -356,9 +355,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
} }
} }
m_EventQueue.RemoveFirst(); m_EventQueue.RemoveFirst();
evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), if (evc >= 0)
evt.EventName); m_EventCounts[(int)evc] --;
if ((int)evc >= 0) m_EventCounts[(int)evc] --;
} }
/* /*
@ -483,28 +481,25 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* We use this.eventCode == ScriptEventCode.None to indicate we are idle. * We use this.eventCode == ScriptEventCode.None to indicate we are idle.
* So trying to execute ScriptEventCode.None might make a mess. * So trying to execute ScriptEventCode.None might make a mess.
*/ */
if (eventCode == ScriptEventCode.None) { if (eventCode == ScriptEventCode.None)
return new Exception ("Can't process ScriptEventCode.None"); return new Exception ("Can't process ScriptEventCode.None");
}
/* /*
* Silly to even try if there is no handler defined for this event. * Silly to even try if there is no handler defined for this event.
*/ */
if (((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)eventCode] == null)) { if ((eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)eventCode] == null))
return null; return null;
}
/* /*
* The microthread shouldn't be processing any event code. * The microthread shouldn't be processing any event code.
* These are assert checks so we throw them directly as exceptions. * These are assert checks so we throw them directly as exceptions.
*/ */
if (this.eventCode != ScriptEventCode.None) { if (this.eventCode != ScriptEventCode.None)
throw new Exception ("still processing event " + this.eventCode.ToString ()); throw new Exception ("still processing event " + this.eventCode.ToString ());
}
int active = microthread.Active (); int active = microthread.Active ();
if (active != 0) { if (active != 0)
throw new Exception ("microthread is active " + active.ToString ()); throw new Exception ("microthread is active " + active.ToString ());
}
/* /*
* Save eventCode so we know what event handler to run in the microthread. * Save eventCode so we know what event handler to run in the microthread.
@ -956,19 +951,28 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
*/ */
public override void CheckRunWork () public override void CheckRunWork ()
{ {
if(!suspendOnCheckRunHold && ! suspendOnCheckRunTemp)
{
if(Util.GetTimeStampMS() - m_SliceStart < 60.0)
return;
suspendOnCheckRunTemp = true;
}
m_CheckRunPhase = "entered"; m_CheckRunPhase = "entered";
/* /*
* Stay stuck in this loop as long as something wants us suspended. * Stay stuck in this loop as long as something wants us suspended.
*/ */
while (suspendOnCheckRunHold || suspendOnCheckRunTemp) { while (suspendOnCheckRunHold || suspendOnCheckRunTemp)
{
m_CheckRunPhase = "top of while"; m_CheckRunPhase = "top of while";
/* /*
* See if MigrateOutEventHandler() has been called. * See if MigrateOutEventHandler() has been called.
* If so, dump our stack to stackFrames and unwind. * If so, dump our stack to stackFrames and unwind.
*/ */
if (this.captureStackFrames) { if (this.captureStackFrames)
{
/* /*
* Puque our stack to the output stream. * Puque our stack to the output stream.
@ -986,7 +990,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* within the functions should do their normal processing instead of trying to * within the functions should do their normal processing instead of trying to
* restore their state. * restore their state.
*/ */
if (this.callMode == CallMode_RESTORE) { if (this.callMode == CallMode_RESTORE)
{
stackFramesRestored = true; stackFramesRestored = true;
this.callMode = CallMode_NORMAL; this.callMode = CallMode_NORMAL;
} }

View File

@ -39,7 +39,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
* Each sits in a loop checking the Start and Yield queues for * Each sits in a loop checking the Start and Yield queues for
* a script to run and calls the script as a microthread. * a script to run and calls the script as a microthread.
*/ */
public class XMRScriptThread { public class XMRScriptThread
{
private static int m_WakeUpOne = 0; private static int m_WakeUpOne = 0;
public static object m_WakeUpLock = new object(); public static object m_WakeUpLock = new object();
private static Dictionary<Thread,XMRScriptThread> m_AllThreads = new Dictionary<Thread,XMRScriptThread> (); private static Dictionary<Thread,XMRScriptThread> m_AllThreads = new Dictionary<Thread,XMRScriptThread> ();
@ -81,10 +82,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
{ {
engine = eng; engine = eng;
m_Continuations = engine.uThreadCtor.DeclaringType == typeof (ScriptUThread_Con); m_Continuations = engine.uThreadCtor.DeclaringType == typeof (ScriptUThread_Con);
thd = XMREngine.StartMyThread (RunScriptThread, "xmrengine script", ThreadPriority.BelowNormal); // thd = XMREngine.StartMyThread (RunScriptThread, "xmrengine script", ThreadPriority.BelowNormal);
lock (m_AllThreads) { thd = XMREngine.StartMyThread (RunScriptThread, "xmrengine script", ThreadPriority.Normal);
lock (m_AllThreads)
m_AllThreads.Add (thd, this); m_AllThreads.Add (thd, this);
}
} }
public void SuspendThread() public void SuspendThread()
@ -104,19 +106,18 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
m_Exiting = true; m_Exiting = true;
WakeUpScriptThread(); WakeUpScriptThread();
thd.Join(); thd.Join();
lock (m_AllThreads) { lock (m_AllThreads)
m_AllThreads.Remove (thd); m_AllThreads.Remove (thd);
}
thd = null; thd = null;
} }
public void TimeSlice() public void TimeSlice()
{ {
XMRInstance instance = m_RunInstance; XMRInstance instance = m_RunInstance;
if (instance != null) { if (instance != null)
instance.suspendOnCheckRunTemp = true; instance.suspendOnCheckRunTemp = true;
} }
}
/** /**
* @brief Wake up this XMRScriptThread instance. * @brief Wake up this XMRScriptThread instance.