aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs (renamed from OpenSim/Region/ScriptEngine/XMREngine/XMRInstRun.cs)504
1 files changed, 248 insertions, 256 deletions
diff --git a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
index 9654b01..8603fbf 100644
--- a/OpenSim/Region/ScriptEngine/XMREngine/XMRInstRun.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
@@ -32,11 +32,9 @@ using System.Text;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.ScriptEngine.Interfaces;
36using OpenSim.Region.ScriptEngine.Shared; 35using OpenSim.Region.ScriptEngine.Shared;
37using OpenSim.Region.ScriptEngine.Shared.Api; 36using OpenSim.Region.ScriptEngine.Shared.Api;
38using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 37using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
39using OpenSim.Region.ScriptEngine.XMREngine;
40using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
41using log4net; 39using log4net;
42 40
@@ -48,7 +46,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
48using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 46using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
49using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 47using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
50 48
51namespace OpenSim.Region.ScriptEngine.XMREngine 49namespace OpenSim.Region.ScriptEngine.Yengine
52{ 50{
53 public partial class XMRInstance 51 public partial class XMRInstance
54 { 52 {
@@ -65,15 +63,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
65 */ 63 */
66 public void PostEvent(EventParams evt) 64 public void PostEvent(EventParams evt)
67 { 65 {
68 ScriptEventCode evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), 66 ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
69 evt.EventName); 67 evt.EventName);
70 68
71 /* 69 /*
72 * Put event on end of event queue. 70 * Put event on end of event queue.
73 */ 71 */
74 bool startIt = false; 72 bool startIt = false;
75 bool wakeIt = false; 73 bool wakeIt = false;
76 lock (m_QueueLock) 74 lock(m_QueueLock)
77 { 75 {
78 bool construct = (m_IState == XMRInstState.CONSTRUCT); 76 bool construct = (m_IState == XMRInstState.CONSTRUCT);
79 77
@@ -82,49 +80,50 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
82 * We can't be state-specific here because state might be different 80 * We can't be state-specific here because state might be different
83 * by the time this event is dequeued and delivered to the script. 81 * by the time this event is dequeued and delivered to the script.
84 */ 82 */
85 if (!construct && // make sure m_HaveEventHandlers is filled in 83 if(!construct && // make sure m_HaveEventHandlers is filled in
86 ((uint)evc < (uint)m_HaveEventHandlers.Length) && 84 ((uint)evc < (uint)m_HaveEventHandlers.Length) &&
87 !m_HaveEventHandlers[(int)evc]) { // don't bother if we don't have such a handler in any state 85 !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
88 return; 86 return;
89 } 87
90 88
91 /* 89 /*
92 * Not running means we ignore any incoming events. 90 * Not running means we ignore any incoming events.
93 * But queue if still constructing because m_Running is not yet valid. 91 * But queue if still constructing because m_Running is not yet valid.
94 */ 92 */
95 if (!m_Running && !construct) { 93 if(!m_Running && !construct)
96 return; 94 return;
97 }
98 95
99 /* 96 /*
100 * Only so many of each event type allowed to queue. 97 * Only so many of each event type allowed to queue.
101 */ 98 */
102 if ((uint)evc < (uint)m_EventCounts.Length) { 99 if((uint)evc < (uint)m_EventCounts.Length)
103 int maxAllowed = MAXEVENTQUEUE; 100 {
104 if (evc == ScriptEventCode.timer) maxAllowed = 1; 101 if(evc == ScriptEventCode.timer)
105 if (m_EventCounts[(int)evc] >= maxAllowed)
106 { 102 {
107 return; 103 if(m_EventCounts[(int)evc] >= 1)
104 return;
108 } 105 }
109 m_EventCounts[(int)evc] ++; 106 else if(m_EventCounts[(int)evc] >= MAXEVENTQUEUE)
107 return;
108
109 m_EventCounts[(int)evc]++;
110 } 110 }
111 111
112 /* 112 /*
113 * Put event on end of instance's event queue. 113 * Put event on end of instance's event queue.
114 */ 114 */
115 LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt); 115 LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt);
116 switch (evc) { 116 switch(evc)
117 117 {
118 /* 118 /*
119 * These need to go first. The only time we manually 119 * These need to go first. The only time we manually
120 * queue them is for the default state_entry() and we 120 * queue them is for the default state_entry() and we
121 * need to make sure they go before any attach() events 121 * need to make sure they go before any attach() events
122 * so the heapLimit value gets properly initialized. 122 * so the heapLimit value gets properly initialized.
123 */ 123 */
124 case ScriptEventCode.state_entry: { 124 case ScriptEventCode.state_entry:
125 m_EventQueue.AddFirst(lln); 125 m_EventQueue.AddFirst(lln);
126 break; 126 break;
127 }
128 127
129 /* 128 /*
130 * The attach event sneaks to the front of the queue. 129 * The attach event sneaks to the front of the queue.
@@ -134,22 +133,23 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
134 * before attach(NULL_KEY) is executed. 133 * before attach(NULL_KEY) is executed.
135 */ 134 */
136 case ScriptEventCode.attach: 135 case ScriptEventCode.attach:
137 { 136 if(evt.Params[0].ToString() == UUID.Zero.ToString())
138 if (evt.Params[0].ToString() == UUID.Zero.ToString())
139 { 137 {
140 LinkedListNode<EventParams> lln2 = null; 138 LinkedListNode<EventParams> lln2 = null;
141 for (lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next) 139 for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next)
142 { 140 {
143 EventParams evt2 = lln2.Value; 141 EventParams evt2 = lln2.Value;
144 ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), 142 ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
145 evt2.EventName); 143 evt2.EventName);
146 if ((evc2 != ScriptEventCode.state_entry) && 144 if((evc2 != ScriptEventCode.state_entry) &&
147 (evc2 != ScriptEventCode.attach)) break; 145 (evc2 != ScriptEventCode.attach))
146 break;
148 } 147 }
149 if (lln2 == null) 148 if(lln2 == null)
150 m_EventQueue.AddLast(lln); 149 m_EventQueue.AddLast(lln);
151 else 150 else
152 m_EventQueue.AddBefore(lln2, lln); 151 m_EventQueue.AddBefore(lln2, lln);
152
153 /* If we're detaching, limit the qantum. This will also 153 /* If we're detaching, limit the qantum. This will also
154 * cause the script to self-suspend after running this 154 * cause the script to self-suspend after running this
155 * event 155 * event
@@ -160,17 +160,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
160 } 160 }
161 else 161 else
162 m_EventQueue.AddLast(lln); 162 m_EventQueue.AddLast(lln);
163
163 break; 164 break;
164 }
165 165
166 /* 166 /*
167 * All others just go on end in the order queued. 167 * All others just go on end in the order queued.
168 */ 168 */
169 default: 169 default:
170 {
171 m_EventQueue.AddLast(lln); 170 m_EventQueue.AddLast(lln);
172 break; 171 break;
173 }
174 } 172 }
175 173
176 /* 174 /*
@@ -180,7 +178,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
180 * to do the same thing right now. 178 * to do the same thing right now.
181 * Dont' flag it if it's still suspended! 179 * Dont' flag it if it's still suspended!
182 */ 180 */
183 if ((m_IState == XMRInstState.IDLE) && !m_Suspended) 181 if((m_IState == XMRInstState.IDLE) && !m_Suspended)
184 { 182 {
185 m_IState = XMRInstState.ONSTARTQ; 183 m_IState = XMRInstState.ONSTARTQ;
186 startIt = true; 184 startIt = true;
@@ -190,15 +188,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
190 * If instance is sleeping (ie, possibly in xmrEventDequeue), 188 * If instance is sleeping (ie, possibly in xmrEventDequeue),
191 * wake it up if event is in the mask. 189 * wake it up if event is in the mask.
192 */ 190 */
193 if ((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) 191 if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended)
194 { 192 {
195 int evc1 = (int)evc; 193 int evc1 = (int)evc;
196 int evc2 = evc1 - 32; 194 int evc2 = evc1 - 32;
197 if ((((uint)evc1 < (uint)32) && (((m_SleepEventMask1 >> evc1) & 1) != 0)) || 195 if((((uint)evc1 < (uint)32) && (((m_SleepEventMask1 >> evc1) & 1) != 0)) ||
198 (((uint)evc2 < (uint)32) && (((m_SleepEventMask2 >> evc2) & 1) != 0))) 196 (((uint)evc2 < (uint)32) && (((m_SleepEventMask2 >> evc2) & 1) != 0)))
199 {
200 wakeIt = true; 197 wakeIt = true;
201 }
202 } 198 }
203 } 199 }
204 200
@@ -206,13 +202,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
206 * If transitioned from IDLE->ONSTARTQ, actually go insert it 202 * If transitioned from IDLE->ONSTARTQ, actually go insert it
207 * on m_StartQueue and give the RunScriptThread() a wake-up. 203 * on m_StartQueue and give the RunScriptThread() a wake-up.
208 */ 204 */
209 if (startIt) 205 if(startIt)
210 m_Engine.QueueToStart(this); 206 m_Engine.QueueToStart(this);
211 207
212 /* 208 /*
213 * Likewise, if the event mask triggered a wake, wake it up. 209 * Likewise, if the event mask triggered a wake, wake it up.
214 */ 210 */
215 if (wakeIt) 211 if(wakeIt)
216 { 212 {
217 m_SleepUntil = DateTime.MinValue; 213 m_SleepUntil = DateTime.MinValue;
218 m_Engine.WakeFromSleep(this); 214 m_Engine.WakeFromSleep(this);
@@ -234,7 +230,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
234 * up. 230 * up.
235 */ 231 */
236 m_RunOnePhase = "check m_SleepUntil"; 232 m_RunOnePhase = "check m_SleepUntil";
237 if (m_SleepUntil > now) 233 if(m_SleepUntil > now)
238 { 234 {
239 m_RunOnePhase = "return is sleeping"; 235 m_RunOnePhase = "return is sleeping";
240 return XMRInstState.ONSLEEPQ; 236 return XMRInstState.ONSLEEPQ;
@@ -244,7 +240,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
244 * Also, someone may have called Suspend(). 240 * Also, someone may have called Suspend().
245 */ 241 */
246 m_RunOnePhase = "check m_SuspendCount"; 242 m_RunOnePhase = "check m_SuspendCount";
247 if (m_SuspendCount > 0) 243 if(m_SuspendCount > 0)
248 { 244 {
249 m_RunOnePhase = "return is suspended"; 245 m_RunOnePhase = "return is suspended";
250 return XMRInstState.SUSPENDED; 246 return XMRInstState.SUSPENDED;
@@ -256,7 +252,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
256 * back right away, delay a bit so we don't get in infinite loop. 252 * back right away, delay a bit so we don't get in infinite loop.
257 */ 253 */
258 m_RunOnePhase = "lock m_RunLock"; 254 m_RunOnePhase = "lock m_RunLock";
259 if (!Monitor.TryEnter (m_RunLock)) 255 if(!Monitor.TryEnter(m_RunLock))
260 { 256 {
261 m_SleepUntil = now.AddMilliseconds(3); 257 m_SleepUntil = now.AddMilliseconds(3);
262 m_RunOnePhase = "return was locked"; 258 m_RunOnePhase = "return was locked";
@@ -269,23 +265,22 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
269 Exception e = null; 265 Exception e = null;
270 266
271 /* 267 /*
272 * Maybe we have been disposed. 268 * Maybe it has been Disposed()
273 */ 269 */
274 m_RunOnePhase = "check disposed"; 270 if(m_Part == null)
275 if (microthread == null)
276 { 271 {
277 m_RunOnePhase = "return disposed"; 272 m_RunOnePhase = "runone saw it disposed";
278 return XMRInstState.DISPOSED; 273 return XMRInstState.DISPOSED;
279 } 274 }
280 275
281 /* 276 /*
282 * Do some more of the last event if it didn't finish. 277 * Do some more of the last event if it didn't finish.
283 */ 278 */
284 else if (eventCode != ScriptEventCode.None) 279 if(this.eventCode != ScriptEventCode.None)
285 { 280 {
286 lock (m_QueueLock) 281 lock(m_QueueLock)
287 { 282 {
288 if (m_DetachQuantum > 0 && --m_DetachQuantum == 0) 283 if(m_DetachQuantum > 0 && --m_DetachQuantum == 0)
289 { 284 {
290 m_Suspended = true; 285 m_Suspended = true;
291 m_DetachReady.Set(); 286 m_DetachReady.Set();
@@ -296,10 +291,10 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
296 } 291 }
297 292
298 m_RunOnePhase = "resume old event handler"; 293 m_RunOnePhase = "resume old event handler";
299 m_LastRanAt = now; 294 m_LastRanAt = now;
300 m_InstEHSlice ++; 295 m_InstEHSlice++;
301 callMode = CallMode_NORMAL; 296 callMode = CallMode_NORMAL;
302 e = microthread.ResumeEx (); 297 e = ResumeEx();
303 } 298 }
304 299
305 /* 300 /*
@@ -312,7 +307,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
312 EventParams evt = null; 307 EventParams evt = null;
313 ScriptEventCode evc = ScriptEventCode.None; 308 ScriptEventCode evc = ScriptEventCode.None;
314 309
315 lock (m_QueueLock) 310 lock(m_QueueLock)
316 { 311 {
317 312
318 /* We can't get here unless the script has been resumed 313 /* We can't get here unless the script has been resumed
@@ -324,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
324 * out and may be improved in the future. 319 * out and may be improved in the future.
325 */ 320 */
326 321
327 if (m_Suspended) 322 if(m_Suspended)
328 { 323 {
329 m_RunOnePhase = "m_Suspended is set"; 324 m_RunOnePhase = "m_Suspended is set";
330 CheckRunLockInvariants(true); 325 CheckRunLockInvariants(true);
@@ -332,14 +327,14 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
332 } 327 }
333 328
334 m_RunOnePhase = "dequeue event"; 329 m_RunOnePhase = "dequeue event";
335 if (m_EventQueue.First != null) 330 if(m_EventQueue.First != null)
336 { 331 {
337 evt = m_EventQueue.First.Value; 332 evt = m_EventQueue.First.Value;
338 evc = (ScriptEventCode)Enum.Parse (typeof (ScriptEventCode), 333 if(m_DetachQuantum > 0)
339 evt.EventName);
340 if (m_DetachQuantum > 0)
341 { 334 {
342 if (evc != ScriptEventCode.attach) 335 evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
336 evt.EventName);
337 if(evc != ScriptEventCode.attach)
343 { 338 {
344 /* 339 /*
345 * This is the case where the attach event 340 * This is the case where the attach event
@@ -355,17 +350,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
355 } 350 }
356 } 351 }
357 m_EventQueue.RemoveFirst(); 352 m_EventQueue.RemoveFirst();
358 if (evc >= 0) 353 evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
359 m_EventCounts[(int)evc] --; 354 evt.EventName);
355 if((int)evc >= 0)
356 m_EventCounts[(int)evc]--;
360 } 357 }
361 358
362 /* 359 /*
363 * If there is no event to dequeue, don't run this script 360 * If there is no event to dequeue, don't run this script
364 * until another event gets queued. 361 * until another event gets queued.
365 */ 362 */
366 if (evt == null) 363 if(evt == null)
367 { 364 {
368 if (m_DetachQuantum > 0) 365 if(m_DetachQuantum > 0)
369 { 366 {
370 /* 367 /*
371 * This will happen if the attach event has run 368 * This will happen if the attach event has run
@@ -385,19 +382,19 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
385 * Dequeued an event, so start it going until it either 382 * Dequeued an event, so start it going until it either
386 * finishes or it calls CheckRun(). 383 * finishes or it calls CheckRun().
387 */ 384 */
388 m_RunOnePhase = "start event handler"; 385 m_RunOnePhase = "start event handler";
389 m_DetectParams = evt.DetectParams; 386 m_DetectParams = evt.DetectParams;
390 m_LastRanAt = now; 387 m_LastRanAt = now;
391 m_InstEHEvent ++; 388 m_InstEHEvent++;
392 e = StartEventHandler (evc, evt.Params); 389 e = StartEventHandler(evc, evt.Params);
393 } 390 }
394 m_RunOnePhase = "done running"; 391 m_RunOnePhase = "done running";
395 m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; 392 m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds;
396 393
397 /* 394 /*
398 * Maybe it puqued. 395 * Maybe it puqued.
399 */ 396 */
400 if (e != null) 397 if(e != null)
401 { 398 {
402 m_RunOnePhase = "handling exception " + e.Message; 399 m_RunOnePhase = "handling exception " + e.Message;
403 HandleScriptException(e); 400 HandleScriptException(e);
@@ -409,10 +406,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
409 /* 406 /*
410 * If event handler completed, get rid of detect params. 407 * If event handler completed, get rid of detect params.
411 */ 408 */
412 if (this.eventCode == ScriptEventCode.None) 409 if(this.eventCode == ScriptEventCode.None)
413 {
414 m_DetectParams = null; 410 m_DetectParams = null;
415 } 411
416 } 412 }
417 finally 413 finally
418 { 414 {
@@ -432,33 +428,30 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
432 * @brief Immediately after taking m_RunLock or just before releasing it, check invariants. 428 * @brief Immediately after taking m_RunLock or just before releasing it, check invariants.
433 */ 429 */
434 private ScriptEventCode lastEventCode = ScriptEventCode.None; 430 private ScriptEventCode lastEventCode = ScriptEventCode.None;
435 private int lastActive = 0; 431 private bool lastActive = false;
436 private string lastRunPhase = ""; 432 private string lastRunPhase = "";
437 433
438 public void CheckRunLockInvariants(bool throwIt) 434 public void CheckRunLockInvariants(bool throwIt)
439 { 435 {
440 /* 436 /*
441 * If not executing any event handler, active should be 0 indicating the microthread stack is not in use. 437 * If not executing any event handler, there shouldn't be any saved stack frames.
442 * If executing an event handler, active should be -1 indicating stack is in use but suspended. 438 * If executing an event handler, there should be some saved stack frames.
443 */ 439 */
444 IScriptUThread uth = microthread; 440 bool active = (stackFrames != null);
445 if (uth != null) { 441 ScriptEventCode ec = this.eventCode;
446 int active = uth.Active (); 442 if(((ec == ScriptEventCode.None) && active) ||
447 ScriptEventCode ec = this.eventCode; 443 ((ec != ScriptEventCode.None) && !active))
448 if (((ec == ScriptEventCode.None) && (active != 0)) || 444 {
449 ((ec != ScriptEventCode.None) && (active >= 0))) { 445 Console.WriteLine("CheckRunLockInvariants: script=" + m_DescName);
450 Console.WriteLine("CheckRunLockInvariants: script=" + m_DescName); 446 Console.WriteLine("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString());
451 Console.WriteLine("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString()); 447 Console.WriteLine("CheckRunLockInvariants: m_RunOnePhase=" + m_RunOnePhase);
452 Console.WriteLine("CheckRunLockInvariants: m_RunOnePhase=" + m_RunOnePhase); 448 Console.WriteLine("CheckRunLockInvariants: lastec=" + lastEventCode + ", lastAct=" + lastActive + ", lastPhase=" + lastRunPhase);
453 Console.WriteLine("CheckRunLockInvariants: lastec=" + lastEventCode + ", lastAct=" + lastActive + ", lastPhase=" + lastRunPhase); 449 if(throwIt)
454 if (throwIt) { 450 throw new Exception("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString());
455 throw new Exception("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString());
456 }
457 }
458 lastEventCode = ec;
459 lastActive = active;
460 lastRunPhase = m_RunOnePhase;
461 } 451 }
452 lastEventCode = ec;
453 lastActive = active;
454 lastRunPhase = m_RunOnePhase;
462 } 455 }
463 456
464 /* 457 /*
@@ -475,38 +468,34 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
475 * from ehArgs[] and will throw an array bounds or cast exception 468 * from ehArgs[] and will throw an array bounds or cast exception
476 * if it can't. 469 * if it can't.
477 */ 470 */
478 private Exception StartEventHandler (ScriptEventCode eventCode, object[] ehArgs) 471 private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs)
479 { 472 {
480 /* 473 /*
481 * We use this.eventCode == ScriptEventCode.None to indicate we are idle. 474 * We use this.eventCode == ScriptEventCode.None to indicate we are idle.
482 * So trying to execute ScriptEventCode.None might make a mess. 475 * So trying to execute ScriptEventCode.None might make a mess.
483 */ 476 */
484 if (eventCode == ScriptEventCode.None) 477 if(eventCode == ScriptEventCode.None)
485 return new Exception ("Can't process ScriptEventCode.None"); 478 return new Exception("Can't process ScriptEventCode.None");
486 479
487 /* 480 /*
488 * Silly to even try if there is no handler defined for this event. 481 * Silly to even try if there is no handler defined for this event.
489 */ 482 */
490 if ((eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode,(int)eventCode] == null)) 483 if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null))
491 return null; 484 return null;
492 485
493 /* 486 /*
494 * The microthread shouldn't be processing any event code. 487 * The microthread shouldn't be processing any event code.
495 * These are assert checks so we throw them directly as exceptions. 488 * These are assert checks so we throw them directly as exceptions.
496 */ 489 */
497 if (this.eventCode != ScriptEventCode.None) 490 if(this.eventCode != ScriptEventCode.None)
498 throw new Exception ("still processing event " + this.eventCode.ToString ()); 491 throw new Exception("still processing event " + this.eventCode.ToString());
499
500 int active = microthread.Active ();
501 if (active != 0)
502 throw new Exception ("microthread is active " + active.ToString ());
503 492
504 /* 493 /*
505 * Save eventCode so we know what event handler to run in the microthread. 494 * Save eventCode so we know what event handler to run in the microthread.
506 * And it also marks us busy so we can't be started again and this event lost. 495 * And it also marks us busy so we can't be started again and this event lost.
507 */ 496 */
508 this.eventCode = eventCode; 497 this.eventCode = eventCode;
509 this.ehArgs = ehArgs; 498 this.ehArgs = ehArgs;
510 499
511 /* 500 /*
512 * This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] 501 * This calls ScriptUThread.Main() directly, and returns when Main() [indirectly]
@@ -515,9 +504,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
515 * without doing any stack frame restores first. 504 * without doing any stack frame restores first.
516 */ 505 */
517 this.stackFrames = null; 506 this.stackFrames = null;
518 Exception e; 507 return StartEx();
519 e = microthread.StartEx ();
520 return e;
521 } 508 }
522 509
523 510
@@ -533,17 +520,17 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
533 */ 520 */
534 eventCode = ScriptEventCode.None; 521 eventCode = ScriptEventCode.None;
535 522
536 if (e is ScriptDeleteException) 523 if(e is ScriptDeleteException)
537 { 524 {
538 /* 525 /*
539 * Script did something like llRemoveInventory(llGetScriptName()); 526 * Script did something like llRemoveInventory(llGetScriptName());
540 * ... to delete itself from the object. 527 * ... to delete itself from the object.
541 */ 528 */
542 m_SleepUntil = DateTime.MaxValue; 529 m_SleepUntil = DateTime.MaxValue;
543 Verbose ("[XMREngine]: script self-delete {0}", m_ItemID); 530 Verbose("[YEngine]: script self-delete {0}", m_ItemID);
544 m_Part.Inventory.RemoveInventoryItem(m_ItemID); 531 m_Part.Inventory.RemoveInventoryItem(m_ItemID);
545 } 532 }
546 else if (e is ScriptDieException) 533 else if(e is ScriptDieException)
547 { 534 {
548 /* 535 /*
549 * Script did an llDie() 536 * Script did an llDie()
@@ -552,7 +539,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
552 m_SleepUntil = DateTime.MaxValue; 539 m_SleepUntil = DateTime.MaxValue;
553 m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); 540 m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false);
554 } 541 }
555 else if (e is ScriptResetException) 542 else if(e is ScriptResetException)
556 { 543 {
557 /* 544 /*
558 * Script did an llResetScript(). 545 * Script did an llResetScript().
@@ -579,63 +566,68 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
579 { 566 {
580 StringBuilder msg = new StringBuilder(); 567 StringBuilder msg = new StringBuilder();
581 568
582 msg.Append ("[XMREngine]: Exception while running "); 569 msg.Append("[YEngine]: Exception while running ");
583 msg.Append (m_ItemID); 570 msg.Append(m_ItemID);
584 msg.Append ('\n'); 571 msg.Append('\n');
585 572
586 /* 573 /*
587 * Add exception message. 574 * Add exception message.
588 */ 575 */
589 string des = e.Message; 576 string des = e.Message;
590 des = (des == null) ? "" : (": " + des); 577 des = (des == null) ? "" : (": " + des);
591 msg.Append (e.GetType ().Name + des + "\n"); 578 msg.Append(e.GetType().Name + des + "\n");
592 579
593 /* 580 /*
594 * Tell script owner what to do. 581 * Tell script owner what to do.
595 */ 582 */
596 msg.Append ("Prim: <"); 583 msg.Append("Prim: <");
597 msg.Append (m_Part.Name); 584 msg.Append(m_Part.Name);
598 msg.Append (">, Script: <"); 585 msg.Append(">, Script: <");
599 msg.Append (m_Item.Name); 586 msg.Append(m_Item.Name);
600 msg.Append (">, Location: "); 587 msg.Append(">, Location: ");
601 msg.Append (m_Engine.World.RegionInfo.RegionName); 588 msg.Append(m_Engine.World.RegionInfo.RegionName);
602 msg.Append (" <"); 589 msg.Append(" <");
603 Vector3 pos = m_Part.AbsolutePosition; 590 Vector3 pos = m_Part.AbsolutePosition;
604 msg.Append ((int) Math.Floor (pos.X)); 591 msg.Append((int)Math.Floor(pos.X));
605 msg.Append (','); 592 msg.Append(',');
606 msg.Append ((int) Math.Floor (pos.Y)); 593 msg.Append((int)Math.Floor(pos.Y));
607 msg.Append (','); 594 msg.Append(',');
608 msg.Append ((int) Math.Floor (pos.Z)); 595 msg.Append((int)Math.Floor(pos.Z));
609 msg.Append (">\nScript must be Reset to re-enable.\n"); 596 msg.Append(">\nScript must be Reset to re-enable.\n");
610 597
611 /* 598 /*
612 * Display full exception message in log. 599 * Display full exception message in log.
613 */ 600 */
614 m_log.Info (msg.ToString() + XMRExceptionStackString (e), e); 601 m_log.Info(msg.ToString() + XMRExceptionStackString(e), e);
615 602
616 /* 603 /*
617 * Give script owner the stack dump. 604 * Give script owner the stack dump.
618 */ 605 */
619 msg.Append (XMRExceptionStackString (e)); 606 msg.Append(XMRExceptionStackString(e));
620 607
621 /* 608 /*
622 * Send error message to owner. 609 * Send error message to owner.
623 * Suppress internal code stack trace lines. 610 * Suppress internal code stack trace lines.
624 */ 611 */
625 string msgst = msg.ToString(); 612 string msgst = msg.ToString();
626 if (!msgst.EndsWith ("\n")) msgst += '\n'; 613 if(!msgst.EndsWith("\n"))
614 msgst += '\n';
627 int j = 0; 615 int j = 0;
628 StringBuilder imstr = new StringBuilder (); 616 StringBuilder imstr = new StringBuilder();
629 for (int i = 0; (i = msgst.IndexOf ('\n', i)) >= 0; j = ++ i) { 617 for(int i = 0; (i = msgst.IndexOf('\n', i)) >= 0; j = ++i)
630 string line = msgst.Substring (j, i - j); 618 {
631 if (line.StartsWith ("at ")) { 619 string line = msgst.Substring(j, i - j);
632 if (line.StartsWith ("at (wrapper")) continue; // at (wrapper ... 620 if(line.StartsWith("at "))
633 int k = line.LastIndexOf (".cs:"); // ... .cs:linenumber 621 {
634 if (Int32.TryParse (line.Substring (k + 4), out k)) continue; 622 if(line.StartsWith("at (wrapper"))
623 continue; // at (wrapper ...
624 int k = line.LastIndexOf(".cs:"); // ... .cs:linenumber
625 if(Int32.TryParse(line.Substring(k + 4), out k))
626 continue;
635 } 627 }
636 this.llOwnerSay (line); 628 this.llOwnerSay(line);
637 imstr.Append (line); 629 imstr.Append(line);
638 imstr.Append ('\n'); 630 imstr.Append('\n');
639 } 631 }
640 632
641 /* 633 /*
@@ -643,14 +635,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
643 * Code modelled from llInstantMessage(). 635 * Code modelled from llInstantMessage().
644 */ 636 */
645 IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>(); 637 IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>();
646 if (transferModule != null) { 638 if(transferModule != null)
639 {
647 UUID friendTransactionID = UUID.Random(); 640 UUID friendTransactionID = UUID.Random();
648 GridInstantMessage gim = new GridInstantMessage(); 641 GridInstantMessage gim = new GridInstantMessage();
649 gim.fromAgentID = new Guid (m_Part.UUID.ToString()); 642 gim.fromAgentID = new Guid(m_Part.UUID.ToString());
650 gim.toAgentID = new Guid (m_Part.OwnerID.ToString ()); 643 gim.toAgentID = new Guid(m_Part.OwnerID.ToString());
651 gim.imSessionID = new Guid(friendTransactionID.ToString()); 644 gim.imSessionID = new Guid(friendTransactionID.ToString());
652 gim.timestamp = (uint)Util.UnixTimeSinceEpoch(); 645 gim.timestamp = (uint)Util.UnixTimeSinceEpoch();
653 gim.message = imstr.ToString (); 646 gim.message = imstr.ToString();
654 gim.dialog = (byte)19; // messgage from script 647 gim.dialog = (byte)19; // messgage from script
655 gim.fromGroup = false; 648 gim.fromGroup = false;
656 gim.offline = (byte)0; 649 gim.offline = (byte)0;
@@ -663,7 +656,9 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
663 (int)Math.Floor(pos.X), 656 (int)Math.Floor(pos.X),
664 (int)Math.Floor(pos.Y), 657 (int)Math.Floor(pos.Y),
665 (int)Math.Floor(pos.Z)); 658 (int)Math.Floor(pos.Z));
666 transferModule.SendInstantMessage(gim, delegate(bool success) {}); 659 transferModule.SendInstantMessage(gim, delegate (bool success)
660 {
661 });
667 } 662 }
668 663
669 /* 664 /*
@@ -679,16 +674,15 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
679 */ 674 */
680 public void Reset() 675 public void Reset()
681 { 676 {
682 checkstate: 677 checkstate:
683 XMRInstState iState = m_IState; 678 XMRInstState iState = m_IState;
684 switch (iState) { 679 switch(iState)
685 680 {
686 /* 681 /*
687 * If it's really being constructed now, that's about as reset as we get. 682 * If it's really being constructed now, that's about as reset as we get.
688 */ 683 */
689 case XMRInstState.CONSTRUCT: { 684 case XMRInstState.CONSTRUCT:
690 return; 685 return;
691 }
692 686
693 /* 687 /*
694 * If it's idle, that means it is ready to receive a new event. 688 * If it's idle, that means it is ready to receive a new event.
@@ -696,15 +690,16 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
696 * it out of idle, verify that it is still in idle then transition 690 * it out of idle, verify that it is still in idle then transition
697 * it to resetting so no other thread will touch it. 691 * it to resetting so no other thread will touch it.
698 */ 692 */
699 case XMRInstState.IDLE: { 693 case XMRInstState.IDLE:
700 lock (m_QueueLock) { 694 lock(m_QueueLock)
701 if (m_IState == XMRInstState.IDLE) { 695 {
696 if(m_IState == XMRInstState.IDLE)
697 {
702 m_IState = XMRInstState.RESETTING; 698 m_IState = XMRInstState.RESETTING;
703 break; 699 break;
704 } 700 }
705 } 701 }
706 goto checkstate; 702 goto checkstate;
707 }
708 703
709 /* 704 /*
710 * If it's on the start queue, that means it is about to dequeue an 705 * If it's on the start queue, that means it is about to dequeue an
@@ -712,112 +707,108 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
712 * can't be started and transition it to resetting so no other thread 707 * can't be started and transition it to resetting so no other thread
713 * will touch it. 708 * will touch it.
714 */ 709 */
715 case XMRInstState.ONSTARTQ: { 710 case XMRInstState.ONSTARTQ:
716 lock (m_Engine.m_StartQueue) { 711 lock(m_Engine.m_StartQueue)
717 if (m_IState == XMRInstState.ONSTARTQ) { 712 {
713 if(m_IState == XMRInstState.ONSTARTQ)
714 {
718 m_Engine.m_StartQueue.Remove(this); 715 m_Engine.m_StartQueue.Remove(this);
719 m_IState = XMRInstState.RESETTING; 716 m_IState = XMRInstState.RESETTING;
720 break; 717 break;
721 } 718 }
722 } 719 }
723 goto checkstate; 720 goto checkstate;
724 }
725 721
726 /* 722 /*
727 * If it's running, tell CheckRun() to suspend the thread then go back 723 * If it's running, tell CheckRun() to suspend the thread then go back
728 * to see what it got transitioned to. 724 * to see what it got transitioned to.
729 */ 725 */
730 case XMRInstState.RUNNING: { 726 case XMRInstState.RUNNING:
731 suspendOnCheckRunHold = true; 727 suspendOnCheckRunHold = true;
732 lock (m_QueueLock) { } 728 lock(m_QueueLock)
729 {
730 }
733 goto checkstate; 731 goto checkstate;
734 } 732
735 733
736 /* 734 /*
737 * If it's sleeping, remove it from sleep queue and transition it to 735 * If it's sleeping, remove it from sleep queue and transition it to
738 * resetting so no other thread will touch it. 736 * resetting so no other thread will touch it.
739 */ 737 */
740 case XMRInstState.ONSLEEPQ: { 738 case XMRInstState.ONSLEEPQ:
741 lock (m_Engine.m_SleepQueue) { 739 lock(m_Engine.m_SleepQueue)
742 if (m_IState == XMRInstState.ONSLEEPQ) { 740 {
741 if(m_IState == XMRInstState.ONSLEEPQ)
742 {
743 m_Engine.m_SleepQueue.Remove(this); 743 m_Engine.m_SleepQueue.Remove(this);
744 m_IState = XMRInstState.RESETTING; 744 m_IState = XMRInstState.RESETTING;
745 break; 745 break;
746 } 746 }
747 } 747 }
748 goto checkstate; 748 goto checkstate;
749 }
750 749
751 /* 750 /*
752 * It was just removed from the sleep queue and is about to be put 751 * It was just removed from the sleep queue and is about to be put
753 * on the yield queue (ie, is being woken up). 752 * on the yield queue (ie, is being woken up).
754 * Let that thread complete transition and try again. 753 * Let that thread complete transition and try again.
755 */ 754 */
756 case XMRInstState.REMDFROMSLPQ: { 755 case XMRInstState.REMDFROMSLPQ:
757 Sleep (10); 756 Sleep(10);
758 goto checkstate; 757 goto checkstate;
759 }
760 758
761 /* 759 /*
762 * If it's yielding, remove it from yield queue and transition it to 760 * If it's yielding, remove it from yield queue and transition it to
763 * resetting so no other thread will touch it. 761 * resetting so no other thread will touch it.
764 */ 762 */
765 case XMRInstState.ONYIELDQ: { 763 case XMRInstState.ONYIELDQ:
766 lock (m_Engine.m_YieldQueue) { 764 lock(m_Engine.m_YieldQueue)
767 if (m_IState == XMRInstState.ONYIELDQ) { 765 {
766 if(m_IState == XMRInstState.ONYIELDQ)
767 {
768 m_Engine.m_YieldQueue.Remove(this); 768 m_Engine.m_YieldQueue.Remove(this);
769 m_IState = XMRInstState.RESETTING; 769 m_IState = XMRInstState.RESETTING;
770 break; 770 break;
771 } 771 }
772 } 772 }
773 goto checkstate; 773 goto checkstate;
774 }
775 774
776 /* 775 /*
777 * If it just finished running something, let that thread transition it 776 * If it just finished running something, let that thread transition it
778 * to its next state then check again. 777 * to its next state then check again.
779 */ 778 */
780 case XMRInstState.FINISHED: { 779 case XMRInstState.FINISHED:
781 Sleep (10); 780 Sleep(10);
782 goto checkstate; 781 goto checkstate;
783 }
784 782
785 /* 783 /*
786 * If it's disposed, that's about as reset as it gets. 784 * If it's disposed, that's about as reset as it gets.
787 */ 785 */
788 case XMRInstState.DISPOSED: { 786 case XMRInstState.DISPOSED:
789 return; 787 return;
790 }
791 788
792 /* 789 /*
793 * Some other thread is already resetting it, let it finish. 790 * Some other thread is already resetting it, let it finish.
794 */ 791 */
795 case XMRInstState.RESETTING: { 792 case XMRInstState.RESETTING:
796 return; 793 return;
797 }
798 794
799 default: throw new Exception("bad state"); 795
796 default:
797 throw new Exception("bad state");
800 } 798 }
801 799
802 /* 800 /*
803 * This thread transitioned the instance to RESETTING so reset it. 801 * This thread transitioned the instance to RESETTING so reset it.
804 */ 802 */
805 lock (m_RunLock) { 803 lock(m_RunLock)
804 {
806 CheckRunLockInvariants(true); 805 CheckRunLockInvariants(true);
807 806
808 /* 807 /*
809 * No other thread should have transitioned it from RESETTING. 808 * No other thread should have transitioned it from RESETTING.
810 */ 809 */
811 if (m_IState != XMRInstState.RESETTING) throw new Exception("bad state"); 810 if(m_IState != XMRInstState.RESETTING)
812 811 throw new Exception("bad state");
813 /*
814 * If the microthread is active, that means it has call frame
815 * context that we don't want. Throw it out and get a fresh one.
816 */
817 if (microthread.Active () < 0) {
818 microthread.Dispose ();
819 microthread = (IScriptUThread)m_Engine.uThreadCtor.Invoke (new object[] { this });
820 }
821 812
822 /* 813 /*
823 * Mark it idle now so it can get queued to process new stuff. 814 * Mark it idle now so it can get queued to process new stuff.
@@ -836,21 +827,22 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
836 827
837 private void ClearQueueExceptLinkMessages() 828 private void ClearQueueExceptLinkMessages()
838 { 829 {
839 lock (m_QueueLock) { 830 lock(m_QueueLock)
831 {
840 EventParams[] linkMessages = new EventParams[m_EventQueue.Count]; 832 EventParams[] linkMessages = new EventParams[m_EventQueue.Count];
841 int n = 0; 833 int n = 0;
842 foreach (EventParams evt2 in m_EventQueue) { 834 foreach(EventParams evt2 in m_EventQueue)
843 if (evt2.EventName == "link_message") { 835 {
836 if(evt2.EventName == "link_message")
844 linkMessages[n++] = evt2; 837 linkMessages[n++] = evt2;
845 }
846 } 838 }
847 839
848 m_EventQueue.Clear(); 840 m_EventQueue.Clear();
849 for (int i = m_EventCounts.Length; -- i >= 0;) m_EventCounts[i] = 0; 841 for(int i = m_EventCounts.Length; --i >= 0;)
842 m_EventCounts[i] = 0;
850 843
851 for (int i = 0; i < n; i ++) { 844 for(int i = 0; i < n; i++)
852 m_EventQueue.AddLast(linkMessages[i]); 845 m_EventQueue.AddLast(linkMessages[i]);
853 }
854 846
855 m_EventCounts[(int)ScriptEventCode.link_message] = n; 847 m_EventCounts[(int)ScriptEventCode.link_message] = n;
856 } 848 }
@@ -858,10 +850,11 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
858 850
859 private void ClearQueue() 851 private void ClearQueue()
860 { 852 {
861 lock (m_QueueLock) 853 lock(m_QueueLock)
862 { 854 {
863 m_EventQueue.Clear(); // no events queued 855 m_EventQueue.Clear(); // no events queued
864 for (int i = m_EventCounts.Length; -- i >= 0;) m_EventCounts[i] = 0; 856 for(int i = m_EventCounts.Length; --i >= 0;)
857 m_EventCounts[i] = 0;
865 } 858 }
866 } 859 }
867 860
@@ -882,7 +875,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
882 m_Part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0; 875 m_Part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0;
883 m_Part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero; 876 m_Part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero;
884 IUrlModule urlModule = m_Engine.World.RequestModuleInterface<IUrlModule>(); 877 IUrlModule urlModule = m_Engine.World.RequestModuleInterface<IUrlModule>();
885 if (urlModule != null) 878 if(urlModule != null)
886 urlModule.ScriptRemoved(m_ItemID); 879 urlModule.ScriptRemoved(m_ItemID);
887 880
888 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 881 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
@@ -890,8 +883,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
890 m_RunOnePhase = "ResetLocked: clearing current event"; 883 m_RunOnePhase = "ResetLocked: clearing current event";
891 this.eventCode = ScriptEventCode.None; // not processing an event 884 this.eventCode = ScriptEventCode.None; // not processing an event
892 m_DetectParams = null; // not processing an event 885 m_DetectParams = null; // not processing an event
893 m_SleepUntil = DateTime.MinValue; // not doing llSleep() 886 m_SleepUntil = DateTime.MinValue; // not doing llSleep()
894 m_ResetCount ++; // has been reset once more 887 m_ResetCount++; // has been reset once more
895 888
896 /* 889 /*
897 * Tell next call to 'default state_entry()' to reset all global 890 * Tell next call to 'default state_entry()' to reset all global
@@ -906,8 +899,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
906 m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; 899 m_RunOnePhase = "ResetLocked: posting default:state_entry() event";
907 stateCode = 0; 900 stateCode = 0;
908 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); 901 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0));
909 PostEvent(new EventParams("state_entry", 902 PostEvent(new EventParams("state_entry",
910 zeroObjectArray, 903 zeroObjectArray,
911 zeroDetectParams)); 904 zeroDetectParams));
912 905
913 /* 906 /*
@@ -920,27 +913,30 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
920 913
921 private void ReleaseControls() 914 private void ReleaseControls()
922 { 915 {
923 if (m_Part != null) 916 if(m_Part != null)
924 { 917 {
925 bool found; 918 bool found;
926 int permsMask; 919 int permsMask;
927 UUID permsGranter; 920 UUID permsGranter;
928 921
929 try { 922 try
923 {
930 permsGranter = m_Part.TaskInventory[m_ItemID].PermsGranter; 924 permsGranter = m_Part.TaskInventory[m_ItemID].PermsGranter;
931 permsMask = m_Part.TaskInventory[m_ItemID].PermsMask; 925 permsMask = m_Part.TaskInventory[m_ItemID].PermsMask;
932 found = true; 926 found = true;
933 } catch { 927 }
928 catch
929 {
934 permsGranter = UUID.Zero; 930 permsGranter = UUID.Zero;
935 permsMask = 0; 931 permsMask = 0;
936 found = false; 932 found = false;
937 } 933 }
938 934
939 if (found && ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)) { 935 if(found && ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0))
936 {
940 ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter); 937 ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter);
941 if (presence != null) { 938 if(presence != null)
942 presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID); 939 presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID);
943 }
944 } 940 }
945 } 941 }
946 } 942 }
@@ -949,61 +945,53 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
949 * @brief The script code should call this routine whenever it is 945 * @brief The script code should call this routine whenever it is
950 * convenient to perform a migation or switch microthreads. 946 * convenient to perform a migation or switch microthreads.
951 */ 947 */
952 public override void CheckRunWork () 948 public override void CheckRunWork()
953 { 949 {
954 if(!suspendOnCheckRunHold && ! suspendOnCheckRunTemp) 950 if(!suspendOnCheckRunHold && !suspendOnCheckRunTemp)
955 { 951 {
956 if(Util.GetTimeStampMS() - m_SliceStart < 60.0) 952 if(Util.GetTimeStampMS() - m_SliceStart < 60.0)
957 return; 953 return;
958 suspendOnCheckRunTemp = true; 954 suspendOnCheckRunTemp = true;
959 } 955 }
960
961 m_CheckRunPhase = "entered"; 956 m_CheckRunPhase = "entered";
962 957
963 /* 958 /*
964 * Stay stuck in this loop as long as something wants us suspended. 959 * Stay stuck in this loop as long as something wants us suspended.
965 */ 960 */
966 while (suspendOnCheckRunHold || suspendOnCheckRunTemp) 961 while(suspendOnCheckRunHold || suspendOnCheckRunTemp)
967 { 962 {
968 m_CheckRunPhase = "top of while"; 963 m_CheckRunPhase = "top of while";
964 suspendOnCheckRunTemp = false;
969 965
970 /* 966 switch(this.callMode)
971 * See if MigrateOutEventHandler() has been called.
972 * If so, dump our stack to stackFrames and unwind.
973 */
974 if (this.captureStackFrames)
975 { 967 {
968 // Now we are ready to suspend the microthread.
969 // This is like a longjmp() to the most recent StartEx() or ResumeEx()
970 // with a simultaneous setjmp() so ResumeEx() can longjmp() back here.
971
972 // the script event handler wants to hibernate
973 // capture stack frames and unwind to Start() or Resume()
974 case CallMode_NORMAL:
975 m_CheckRunPhase = "suspending";
976 callMode = XMRInstance.CallMode_SAVE;
977 stackFrames = null;
978 throw new StackHibernateException();
979
980 // We get here when the script state has been read in by MigrateInEventHandler().
981 // Since the stack is completely restored at this point, any subsequent calls
982 // within the functions should do their normal processing instead of trying to
983 // restore their state.
984
985 // the stack has been restored as a result of calling ResumeEx()
986 // tell script code to process calls normally
987 case CallMode_RESTORE:
988 this.callMode = CallMode_NORMAL;
989 break;
976 990
977 /* 991 default:
978 * Puque our stack to the output stream. 992 throw new Exception("callMode=" + callMode);
979 * But otherwise, our state remains intact.
980 */
981 m_CheckRunPhase = "saving";
982 this.callMode = CallMode_SAVE;
983 this.stackFrames = null;
984 throw new StackCaptureException ();
985 }
986
987 /*
988 * We get here when the script state has been read in by MigrateInEventHandler().
989 * Since the stack is completely restored at this point, any subsequent calls
990 * within the functions should do their normal processing instead of trying to
991 * restore their state.
992 */
993 if (this.callMode == CallMode_RESTORE)
994 {
995 stackFramesRestored = true;
996 this.callMode = CallMode_NORMAL;
997 } 993 }
998 994
999 /*
1000 * Now we are ready to suspend the microthread.
1001 * This is like a longjmp() to the most recent StartEx() or ResumeEx()
1002 * with a simultaneous setjmp() so ResumeEx() can longjmp() back here.
1003 */
1004 m_CheckRunPhase = "suspending";
1005 suspendOnCheckRunTemp = false;
1006 microthread.Hiber ();
1007 m_CheckRunPhase = "resumed"; 995 m_CheckRunPhase = "resumed";
1008 } 996 }
1009 997
@@ -1013,7 +1001,8 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1013 * Upon return from CheckRun() it should always be the case that the script is 1001 * Upon return from CheckRun() it should always be the case that the script is
1014 * going to process calls normally, neither saving nor restoring stack frame state. 1002 * going to process calls normally, neither saving nor restoring stack frame state.
1015 */ 1003 */
1016 if (callMode != CallMode_NORMAL) throw new Exception ("bad callMode " + callMode); 1004 if(callMode != CallMode_NORMAL)
1005 throw new Exception("bad callMode " + callMode);
1017 } 1006 }
1018 1007
1019 /** 1008 /**
@@ -1021,12 +1010,13 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1021 */ 1010 */
1022 public void ResumeIt() 1011 public void ResumeIt()
1023 { 1012 {
1024 lock (m_QueueLock) 1013 lock(m_QueueLock)
1025 { 1014 {
1026 m_Suspended = false; 1015 m_Suspended = false;
1027 if ((m_EventQueue != null) && 1016 if((m_EventQueue != null) &&
1028 (m_EventQueue.First != null) && 1017 (m_EventQueue.First != null) &&
1029 (m_IState == XMRInstState.IDLE)) { 1018 (m_IState == XMRInstState.IDLE))
1019 {
1030 m_IState = XMRInstState.ONSTARTQ; 1020 m_IState = XMRInstState.ONSTARTQ;
1031 m_Engine.QueueToStart(this); 1021 m_Engine.QueueToStart(this);
1032 } 1022 }
@@ -1039,7 +1029,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1039 */ 1029 */
1040 public void SuspendIt() 1030 public void SuspendIt()
1041 { 1031 {
1042 lock (m_QueueLock) 1032 lock(m_QueueLock)
1043 { 1033 {
1044 m_Suspended = true; 1034 m_Suspended = true;
1045 } 1035 }
@@ -1052,5 +1042,7 @@ namespace OpenSim.Region.ScriptEngine.XMREngine
1052 * to intercept this exception as it would block the stack capture 1042 * to intercept this exception as it would block the stack capture
1053 * functionality. 1043 * functionality.
1054 */ 1044 */
1055 public class StackCaptureException : Exception, IXMRUncatchable { } 1045 public class StackCaptureException: Exception, IXMRUncatchable
1046 {
1047 }
1056} 1048}