aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
diff options
context:
space:
mode:
authorUbitUmarov2018-02-25 00:18:41 +0000
committerUbitUmarov2018-02-25 00:18:41 +0000
commit85b973ce1d8dc034546c9c572a7f57e73b6017d3 (patch)
treea03332d9233e3788f8bc2e535b6863d8fe195b0b /OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
parentYengine fix its section name on opensim.ini.example (diff)
downloadopensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.zip
opensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.tar.gz
opensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.tar.bz2
opensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.tar.xz
Y(xmr)engine cosmetics...
Diffstat (limited to 'OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs387
1 files changed, 127 insertions, 260 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
index 8603fbf..8ac9794 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
@@ -66,36 +66,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine
66 ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), 66 ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
67 evt.EventName); 67 evt.EventName);
68 68
69 /* 69 // Put event on end of event queue.
70 * Put event on end of event queue.
71 */
72 bool startIt = false; 70 bool startIt = false;
73 bool wakeIt = false; 71 bool wakeIt = false;
74 lock(m_QueueLock) 72 lock(m_QueueLock)
75 { 73 {
76 bool construct = (m_IState == XMRInstState.CONSTRUCT); 74 bool construct = (m_IState == XMRInstState.CONSTRUCT);
77 75
78 /* 76 // Ignore event if we don't even have such an handler in any state.
79 * Ignore event if we don't even have such an handler in any state. 77 // 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 78 // 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.
82 */
83 if(!construct && // make sure m_HaveEventHandlers is filled in 79 if(!construct && // make sure m_HaveEventHandlers is filled in
84 ((uint)evc < (uint)m_HaveEventHandlers.Length) && 80 ((uint)evc < (uint)m_HaveEventHandlers.Length) &&
85 !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state 81 !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
86 return; 82 return;
87 83
88 84 // Not running means we ignore any incoming events.
89 /* 85 // But queue if still constructing because m_Running is not yet valid.
90 * Not running means we ignore any incoming events.
91 * But queue if still constructing because m_Running is not yet valid.
92 */
93 if(!m_Running && !construct) 86 if(!m_Running && !construct)
94 return; 87 return;
95 88
96 /* 89 // Only so many of each event type allowed to queue.
97 * Only so many of each event type allowed to queue.
98 */
99 if((uint)evc < (uint)m_EventCounts.Length) 90 if((uint)evc < (uint)m_EventCounts.Length)
100 { 91 {
101 if(evc == ScriptEventCode.timer) 92 if(evc == ScriptEventCode.timer)
@@ -109,29 +100,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
109 m_EventCounts[(int)evc]++; 100 m_EventCounts[(int)evc]++;
110 } 101 }
111 102
112 /* 103 // Put event on end of instance's event queue.
113 * Put event on end of instance's event queue.
114 */
115 LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt); 104 LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt);
116 switch(evc) 105 switch(evc)
117 { 106 {
118 /* 107 // These need to go first. The only time we manually
119 * These need to go first. The only time we manually 108 // queue them is for the default state_entry() and we
120 * queue them is for the default state_entry() and we 109 // need to make sure they go before any attach() events
121 * need to make sure they go before any attach() events 110 // so the heapLimit value gets properly initialized.
122 * so the heapLimit value gets properly initialized.
123 */
124 case ScriptEventCode.state_entry: 111 case ScriptEventCode.state_entry:
125 m_EventQueue.AddFirst(lln); 112 m_EventQueue.AddFirst(lln);
126 break; 113 break;
127 114
128 /* 115 // The attach event sneaks to the front of the queue.
129 * The attach event sneaks to the front of the queue. 116 // This is needed for quantum limiting to work because
130 * This is needed for quantum limiting to work because 117 // we want the attach(NULL_KEY) event to come in front
131 * we want the attach(NULL_KEY) event to come in front 118 // of all others so the m_DetachQuantum won't run out
132 * of all others so the m_DetachQuantum won't run out 119 // before attach(NULL_KEY) is executed.
133 * before attach(NULL_KEY) is executed.
134 */
135 case ScriptEventCode.attach: 120 case ScriptEventCode.attach:
136 if(evt.Params[0].ToString() == UUID.Zero.ToString()) 121 if(evt.Params[0].ToString() == UUID.Zero.ToString())
137 { 122 {
@@ -150,11 +135,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
150 else 135 else
151 m_EventQueue.AddBefore(lln2, lln); 136 m_EventQueue.AddBefore(lln2, lln);
152 137
153 /* If we're detaching, limit the qantum. This will also 138 // If we're detaching, limit the qantum. This will also
154 * cause the script to self-suspend after running this 139 // cause the script to self-suspend after running this
155 * event 140 // event
156 */
157
158 m_DetachReady.Reset(); 141 m_DetachReady.Reset();
159 m_DetachQuantum = 100; 142 m_DetachQuantum = 100;
160 } 143 }
@@ -163,31 +146,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine
163 146
164 break; 147 break;
165 148
166 /* 149 // All others just go on end in the order queued.
167 * All others just go on end in the order queued.
168 */
169 default: 150 default:
170 m_EventQueue.AddLast(lln); 151 m_EventQueue.AddLast(lln);
171 break; 152 break;
172 } 153 }
173 154
174 /* 155 // If instance is idle (ie, not running or waiting to run),
175 * If instance is idle (ie, not running or waiting to run), 156 // flag it to be on m_StartQueue as we are about to do so.
176 * flag it to be on m_StartQueue as we are about to do so. 157 // Flag it now before unlocking so another thread won't try
177 * Flag it now before unlocking so another thread won't try 158 // to do the same thing right now.
178 * to do the same thing right now. 159 // Dont' flag it if it's still suspended!
179 * Dont' flag it if it's still suspended!
180 */
181 if((m_IState == XMRInstState.IDLE) && !m_Suspended) 160 if((m_IState == XMRInstState.IDLE) && !m_Suspended)
182 { 161 {
183 m_IState = XMRInstState.ONSTARTQ; 162 m_IState = XMRInstState.ONSTARTQ;
184 startIt = true; 163 startIt = true;
185 } 164 }
186 165
187 /* 166 // If instance is sleeping (ie, possibly in xmrEventDequeue),
188 * If instance is sleeping (ie, possibly in xmrEventDequeue), 167 // wake it up if event is in the mask.
189 * wake it up if event is in the mask.
190 */
191 if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) 168 if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended)
192 { 169 {
193 int evc1 = (int)evc; 170 int evc1 = (int)evc;
@@ -198,16 +175,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
198 } 175 }
199 } 176 }
200 177
201 /* 178 // If transitioned from IDLE->ONSTARTQ, actually go insert it
202 * If transitioned from IDLE->ONSTARTQ, actually go insert it 179 // on m_StartQueue and give the RunScriptThread() a wake-up.
203 * on m_StartQueue and give the RunScriptThread() a wake-up.
204 */
205 if(startIt) 180 if(startIt)
206 m_Engine.QueueToStart(this); 181 m_Engine.QueueToStart(this);
207 182
208 /* 183 // Likewise, if the event mask triggered a wake, wake it up.
209 * Likewise, if the event mask triggered a wake, wake it up.
210 */
211 if(wakeIt) 184 if(wakeIt)
212 { 185 {
213 m_SleepUntil = DateTime.MinValue; 186 m_SleepUntil = DateTime.MinValue;
@@ -215,20 +188,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
215 } 188 }
216 } 189 }
217 190
218 /* 191 // This is called in the script thread to step script until it calls
219 * This is called in the script thread to step script until it calls 192 // CheckRun(). It returns what the instance's next state should be,
220 * CheckRun(). It returns what the instance's next state should be, 193 // ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
221 * ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
222 */
223 public XMRInstState RunOne() 194 public XMRInstState RunOne()
224 { 195 {
225 DateTime now = DateTime.UtcNow; 196 DateTime now = DateTime.UtcNow;
226 m_SliceStart = Util.GetTimeStampMS(); 197 m_SliceStart = Util.GetTimeStampMS();
227 198
228 /* 199 // If script has called llSleep(), don't do any more until time is up.
229 * If script has called llSleep(), don't do any more until time is
230 * up.
231 */
232 m_RunOnePhase = "check m_SleepUntil"; 200 m_RunOnePhase = "check m_SleepUntil";
233 if(m_SleepUntil > now) 201 if(m_SleepUntil > now)
234 { 202 {
@@ -236,9 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
236 return XMRInstState.ONSLEEPQ; 204 return XMRInstState.ONSLEEPQ;
237 } 205 }
238 206
239 /* 207 // Also, someone may have called Suspend().
240 * Also, someone may have called Suspend().
241 */
242 m_RunOnePhase = "check m_SuspendCount"; 208 m_RunOnePhase = "check m_SuspendCount";
243 if(m_SuspendCount > 0) 209 if(m_SuspendCount > 0)
244 { 210 {
@@ -246,11 +212,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
246 return XMRInstState.SUSPENDED; 212 return XMRInstState.SUSPENDED;
247 } 213 }
248 214
249 /* 215 // Make sure we aren't being migrated in or out and prevent that
250 * Make sure we aren't being migrated in or out and prevent that 216 // whilst we are in here. If migration has it locked, don't call
251 * whilst we are in here. If migration has it locked, don't call 217 // 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.
253 */
254 m_RunOnePhase = "lock m_RunLock"; 218 m_RunOnePhase = "lock m_RunLock";
255 if(!Monitor.TryEnter(m_RunLock)) 219 if(!Monitor.TryEnter(m_RunLock))
256 { 220 {
@@ -264,18 +228,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
264 CheckRunLockInvariants(true); 228 CheckRunLockInvariants(true);
265 Exception e = null; 229 Exception e = null;
266 230
267 /* 231 // Maybe it has been Disposed()
268 * Maybe it has been Disposed()
269 */
270 if(m_Part == null) 232 if(m_Part == null)
271 { 233 {
272 m_RunOnePhase = "runone saw it disposed"; 234 m_RunOnePhase = "runone saw it disposed";
273 return XMRInstState.DISPOSED; 235 return XMRInstState.DISPOSED;
274 } 236 }
275 237
276 /* 238 // 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.
278 */
279 if(this.eventCode != ScriptEventCode.None) 239 if(this.eventCode != ScriptEventCode.None)
280 { 240 {
281 lock(m_QueueLock) 241 lock(m_QueueLock)
@@ -297,10 +257,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
297 e = ResumeEx(); 257 e = ResumeEx();
298 } 258 }
299 259
300 /* 260 // Otherwise, maybe we can dequeue a new event and start
301 * Otherwise, maybe we can dequeue a new event and start 261 // processing it.
302 * processing it.
303 */
304 else 262 else
305 { 263 {
306 m_RunOnePhase = "lock event queue"; 264 m_RunOnePhase = "lock event queue";
@@ -310,14 +268,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
310 lock(m_QueueLock) 268 lock(m_QueueLock)
311 { 269 {
312 270
313 /* We can't get here unless the script has been resumed 271 // We can't get here unless the script has been resumed
314 * after creation, then suspended again, and then had 272 // after creation, then suspended again, and then had
315 * an event posted to it. We just pretend there is no 273 // an event posted to it. We just pretend there is no
316 * event int he queue and let the normal mechanics 274 // event int he queue and let the normal mechanics
317 * carry out the suspension. A Resume will handle the 275 // carry out the suspension. A Resume will handle the
318 * restarting gracefully. This is taking the easy way 276 // restarting gracefully. This is taking the easy way
319 * out and may be improved in the future. 277 // out and may be improved in the future.
320 */
321 278
322 if(m_Suspended) 279 if(m_Suspended)
323 { 280 {
@@ -336,11 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
336 evt.EventName); 293 evt.EventName);
337 if(evc != ScriptEventCode.attach) 294 if(evc != ScriptEventCode.attach)
338 { 295 {
339 /* 296 // This is the case where the attach event
340 * This is the case where the attach event 297 // has completed and another event is queued
341 * has completed and another event is queued 298 // Stop it from running and suspend
342 * Stop it from running and suspend
343 */
344 m_Suspended = true; 299 m_Suspended = true;
345 m_DetachReady.Set(); 300 m_DetachReady.Set();
346 m_DetachQuantum = 0; 301 m_DetachQuantum = 0;
@@ -356,18 +311,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
356 m_EventCounts[(int)evc]--; 311 m_EventCounts[(int)evc]--;
357 } 312 }
358 313
359 /* 314 // 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 315 // until another event gets queued.
361 * until another event gets queued.
362 */
363 if(evt == null) 316 if(evt == null)
364 { 317 {
365 if(m_DetachQuantum > 0) 318 if(m_DetachQuantum > 0)
366 { 319 {
367 /* 320 // This will happen if the attach event has run
368 * This will happen if the attach event has run 321 // and exited with time slice left.
369 * and exited with time slice left.
370 */
371 m_Suspended = true; 322 m_Suspended = true;
372 m_DetachReady.Set(); 323 m_DetachReady.Set();
373 m_DetachQuantum = 0; 324 m_DetachQuantum = 0;
@@ -378,10 +329,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
378 } 329 }
379 } 330 }
380 331
381 /* 332 // Dequeued an event, so start it going until it either
382 * Dequeued an event, so start it going until it either 333 // finishes or it calls CheckRun().
383 * finishes or it calls CheckRun().
384 */
385 m_RunOnePhase = "start event handler"; 334 m_RunOnePhase = "start event handler";
386 m_DetectParams = evt.DetectParams; 335 m_DetectParams = evt.DetectParams;
387 m_LastRanAt = now; 336 m_LastRanAt = now;
@@ -391,9 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
391 m_RunOnePhase = "done running"; 340 m_RunOnePhase = "done running";
392 m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; 341 m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds;
393 342
394 /* 343 // Maybe it puqued.
395 * Maybe it puqued.
396 */
397 if(e != null) 344 if(e != null)
398 { 345 {
399 m_RunOnePhase = "handling exception " + e.Message; 346 m_RunOnePhase = "handling exception " + e.Message;
@@ -403,9 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
403 return XMRInstState.FINISHED; 350 return XMRInstState.FINISHED;
404 } 351 }
405 352
406 /* 353 // If event handler completed, get rid of detect params.
407 * If event handler completed, get rid of detect params.
408 */
409 if(this.eventCode == ScriptEventCode.None) 354 if(this.eventCode == ScriptEventCode.None)
410 m_DetectParams = null; 355 m_DetectParams = null;
411 356
@@ -417,9 +362,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
417 Monitor.Exit(m_RunLock); 362 Monitor.Exit(m_RunLock);
418 } 363 }
419 364
420 /* 365 // Cycle script through the yield queue and call it back asap.
421 * Cycle script through the yield queue and call it back asap.
422 */
423 m_RunOnePhase = "last return"; 366 m_RunOnePhase = "last return";
424 return XMRInstState.ONYIELDQ; 367 return XMRInstState.ONYIELDQ;
425 } 368 }
@@ -433,10 +376,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
433 376
434 public void CheckRunLockInvariants(bool throwIt) 377 public void CheckRunLockInvariants(bool throwIt)
435 { 378 {
436 /* 379 // If not executing any event handler, there shouldn't be any saved stack frames.
437 * If not executing any event handler, there shouldn't be any saved stack frames. 380 // If executing an event handler, there should be some saved stack frames.
438 * If executing an event handler, there should be some saved stack frames.
439 */
440 bool active = (stackFrames != null); 381 bool active = (stackFrames != null);
441 ScriptEventCode ec = this.eventCode; 382 ScriptEventCode ec = this.eventCode;
442 if(((ec == ScriptEventCode.None) && active) || 383 if(((ec == ScriptEventCode.None) && active) ||
@@ -470,88 +411,67 @@ namespace OpenSim.Region.ScriptEngine.Yengine
470 */ 411 */
471 private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs) 412 private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs)
472 { 413 {
473 /* 414 // We use this.eventCode == ScriptEventCode.None to indicate we are idle.
474 * We use this.eventCode == ScriptEventCode.None to indicate we are idle. 415 // So trying to execute ScriptEventCode.None might make a mess.
475 * So trying to execute ScriptEventCode.None might make a mess.
476 */
477 if(eventCode == ScriptEventCode.None) 416 if(eventCode == ScriptEventCode.None)
478 return new Exception("Can't process ScriptEventCode.None"); 417 return new Exception("Can't process ScriptEventCode.None");
479 418
480 /* 419 // 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.
482 */
483 if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null)) 420 if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null))
484 return null; 421 return null;
485 422
486 /* 423 // The microthread shouldn't be processing any event code.
487 * The microthread shouldn't be processing any event code. 424 // These are assert checks so we throw them directly as exceptions.
488 * These are assert checks so we throw them directly as exceptions.
489 */
490 if(this.eventCode != ScriptEventCode.None) 425 if(this.eventCode != ScriptEventCode.None)
491 throw new Exception("still processing event " + this.eventCode.ToString()); 426 throw new Exception("still processing event " + this.eventCode.ToString());
492 427
493 /* 428 // 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. 429 // 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.
496 */
497 this.eventCode = eventCode; 430 this.eventCode = eventCode;
498 this.ehArgs = ehArgs; 431 this.ehArgs = ehArgs;
499 432
500 /* 433 // This calls ScriptUThread.Main() directly, and returns when Main() [indirectly]
501 * This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] 434 // calls Suspend() or when Main() returns, whichever occurs first.
502 * calls Suspend() or when Main() returns, whichever occurs first. 435 // Setting stackFrames = null means run the event handler from the beginning
503 * Setting stackFrames = null means run the event handler from the beginning 436 // without doing any stack frame restores first.
504 * without doing any stack frame restores first.
505 */
506 this.stackFrames = null; 437 this.stackFrames = null;
507 return StartEx(); 438 return StartEx();
508 } 439 }
509 440
510
511 /** 441 /**
512 * @brief There was an exception whilst starting/running a script event handler. 442 * @brief There was an exception whilst starting/running a script event handler.
513 * Maybe we handle it directly or just print an error message. 443 * Maybe we handle it directly or just print an error message.
514 */ 444 */
515 private void HandleScriptException(Exception e) 445 private void HandleScriptException(Exception e)
516 { 446 {
517 /* 447 // The script threw some kind of exception that was not caught at
518 * The script threw some kind of exception that was not caught at 448 // script level, so the script is no longer running an event handler.
519 * script level, so the script is no longer running an event handler.
520 */
521 eventCode = ScriptEventCode.None; 449 eventCode = ScriptEventCode.None;
522 450
523 if(e is ScriptDeleteException) 451 if(e is ScriptDeleteException)
524 { 452 {
525 /* 453 // Script did something like llRemoveInventory(llGetScriptName());
526 * Script did something like llRemoveInventory(llGetScriptName()); 454 // ... to delete itself from the object.
527 * ... to delete itself from the object.
528 */
529 m_SleepUntil = DateTime.MaxValue; 455 m_SleepUntil = DateTime.MaxValue;
530 Verbose("[YEngine]: script self-delete {0}", m_ItemID); 456 Verbose("[YEngine]: script self-delete {0}", m_ItemID);
531 m_Part.Inventory.RemoveInventoryItem(m_ItemID); 457 m_Part.Inventory.RemoveInventoryItem(m_ItemID);
532 } 458 }
533 else if(e is ScriptDieException) 459 else if(e is ScriptDieException)
534 { 460 {
535 /* 461 // Script did an llDie()
536 * Script did an llDie()
537 */
538 m_RunOnePhase = "dying..."; 462 m_RunOnePhase = "dying...";
539 m_SleepUntil = DateTime.MaxValue; 463 m_SleepUntil = DateTime.MaxValue;
540 m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); 464 m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false);
541 } 465 }
542 else if(e is ScriptResetException) 466 else if(e is ScriptResetException)
543 { 467 {
544 /* 468 // Script did an llResetScript().
545 * Script did an llResetScript().
546 */
547 m_RunOnePhase = "resetting..."; 469 m_RunOnePhase = "resetting...";
548 ResetLocked("HandleScriptResetException"); 470 ResetLocked("HandleScriptResetException");
549 } 471 }
550 else 472 else
551 { 473 {
552 /* 474 // Some general script error.
553 * Some general script error.
554 */
555 SendErrorMessage(e); 475 SendErrorMessage(e);
556 } 476 }
557 return; 477 return;
@@ -570,16 +490,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
570 msg.Append(m_ItemID); 490 msg.Append(m_ItemID);
571 msg.Append('\n'); 491 msg.Append('\n');
572 492
573 /* 493 // Add exception message.
574 * Add exception message.
575 */
576 string des = e.Message; 494 string des = e.Message;
577 des = (des == null) ? "" : (": " + des); 495 des = (des == null) ? "" : (": " + des);
578 msg.Append(e.GetType().Name + des + "\n"); 496 msg.Append(e.GetType().Name + des + "\n");
579 497
580 /* 498 // Tell script owner what to do.
581 * Tell script owner what to do.
582 */
583 msg.Append("Prim: <"); 499 msg.Append("Prim: <");
584 msg.Append(m_Part.Name); 500 msg.Append(m_Part.Name);
585 msg.Append(">, Script: <"); 501 msg.Append(">, Script: <");
@@ -595,20 +511,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
595 msg.Append((int)Math.Floor(pos.Z)); 511 msg.Append((int)Math.Floor(pos.Z));
596 msg.Append(">\nScript must be Reset to re-enable.\n"); 512 msg.Append(">\nScript must be Reset to re-enable.\n");
597 513
598 /* 514 // Display full exception message in log.
599 * Display full exception message in log.
600 */
601 m_log.Info(msg.ToString() + XMRExceptionStackString(e), e); 515 m_log.Info(msg.ToString() + XMRExceptionStackString(e), e);
602 516
603 /* 517 // Give script owner the stack dump.
604 * Give script owner the stack dump.
605 */
606 msg.Append(XMRExceptionStackString(e)); 518 msg.Append(XMRExceptionStackString(e));
607 519
608 /* 520 // Send error message to owner.
609 * Send error message to owner. 521 // Suppress internal code stack trace lines.
610 * Suppress internal code stack trace lines.
611 */
612 string msgst = msg.ToString(); 522 string msgst = msg.ToString();
613 if(!msgst.EndsWith("\n")) 523 if(!msgst.EndsWith("\n"))
614 msgst += '\n'; 524 msgst += '\n';
@@ -630,10 +540,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
630 imstr.Append('\n'); 540 imstr.Append('\n');
631 } 541 }
632 542
633 /* 543 // Send as instant message in case user not online.
634 * Send as instant message in case user not online. 544 // Code modelled from llInstantMessage().
635 * Code modelled from llInstantMessage().
636 */
637 IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>(); 545 IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>();
638 if(transferModule != null) 546 if(transferModule != null)
639 { 547 {
@@ -661,10 +569,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
661 }); 569 });
662 } 570 }
663 571
664 /* 572 // Say script is sleeping for a very long time.
665 * Say script is sleeping for a very long time. 573 // Reset() is able to cancel this sleeping.
666 * Reset() is able to cancel this sleeping.
667 */
668 m_SleepUntil = DateTime.MaxValue; 574 m_SleepUntil = DateTime.MaxValue;
669 } 575 }
670 576
@@ -678,18 +584,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
678 XMRInstState iState = m_IState; 584 XMRInstState iState = m_IState;
679 switch(iState) 585 switch(iState)
680 { 586 {
681 /* 587 // 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.
683 */
684 case XMRInstState.CONSTRUCT: 588 case XMRInstState.CONSTRUCT:
685 return; 589 return;
686 590
687 /* 591 // 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. 592 // So we lock the event queue to prevent another thread from taking
689 * So we lock the event queue to prevent another thread from taking 593 // 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 594 // it to resetting so no other thread will touch it.
691 * it to resetting so no other thread will touch it.
692 */
693 case XMRInstState.IDLE: 595 case XMRInstState.IDLE:
694 lock(m_QueueLock) 596 lock(m_QueueLock)
695 { 597 {
@@ -701,12 +603,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
701 } 603 }
702 goto checkstate; 604 goto checkstate;
703 605
704 /* 606 // 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 607 // event and start processing it. So we lock the start queue so it
706 * event and start processing it. So we lock the start queue so it 608 // 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 609 // will touch it.
708 * will touch it.
709 */
710 case XMRInstState.ONSTARTQ: 610 case XMRInstState.ONSTARTQ:
711 lock(m_Engine.m_StartQueue) 611 lock(m_Engine.m_StartQueue)
712 { 612 {
@@ -719,10 +619,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
719 } 619 }
720 goto checkstate; 620 goto checkstate;
721 621
722 /* 622 // 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 623 // to see what it got transitioned to.
724 * to see what it got transitioned to.
725 */
726 case XMRInstState.RUNNING: 624 case XMRInstState.RUNNING:
727 suspendOnCheckRunHold = true; 625 suspendOnCheckRunHold = true;
728 lock(m_QueueLock) 626 lock(m_QueueLock)
@@ -730,11 +628,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
730 } 628 }
731 goto checkstate; 629 goto checkstate;
732 630
733 631 // If it's sleeping, remove it from sleep queue and transition it to
734 /* 632 // resetting so no other thread will touch it.
735 * If it's sleeping, remove it from sleep queue and transition it to
736 * resetting so no other thread will touch it.
737 */
738 case XMRInstState.ONSLEEPQ: 633 case XMRInstState.ONSLEEPQ:
739 lock(m_Engine.m_SleepQueue) 634 lock(m_Engine.m_SleepQueue)
740 { 635 {
@@ -747,19 +642,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
747 } 642 }
748 goto checkstate; 643 goto checkstate;
749 644
750 /* 645 // 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 646 // on the yield queue (ie, is being woken up).
752 * on the yield queue (ie, is being woken up). 647 // Let that thread complete transition and try again.
753 * Let that thread complete transition and try again.
754 */
755 case XMRInstState.REMDFROMSLPQ: 648 case XMRInstState.REMDFROMSLPQ:
756 Sleep(10); 649 Sleep(10);
757 goto checkstate; 650 goto checkstate;
758 651
759 /* 652 // 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 653 // resetting so no other thread will touch it.
761 * resetting so no other thread will touch it.
762 */
763 case XMRInstState.ONYIELDQ: 654 case XMRInstState.ONYIELDQ:
764 lock(m_Engine.m_YieldQueue) 655 lock(m_Engine.m_YieldQueue)
765 { 656 {
@@ -772,52 +663,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine
772 } 663 }
773 goto checkstate; 664 goto checkstate;
774 665
775 /* 666 // If it just finished running something, let that thread transition it
776 * If it just finished running something, let that thread transition it 667 // to its next state then check again.
777 * to its next state then check again.
778 */
779 case XMRInstState.FINISHED: 668 case XMRInstState.FINISHED:
780 Sleep(10); 669 Sleep(10);
781 goto checkstate; 670 goto checkstate;
782 671
783 /* 672 // 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.
785 */
786 case XMRInstState.DISPOSED: 673 case XMRInstState.DISPOSED:
787 return; 674 return;
788 675
789 /* 676 // Some other thread is already resetting it, let it finish.
790 * Some other thread is already resetting it, let it finish. 677
791 */
792 case XMRInstState.RESETTING: 678 case XMRInstState.RESETTING:
793 return; 679 return;
794 680
795
796 default: 681 default:
797 throw new Exception("bad state"); 682 throw new Exception("bad state");
798 } 683 }
799 684
800 /* 685 // This thread transitioned the instance to RESETTING so reset it.
801 * This thread transitioned the instance to RESETTING so reset it.
802 */
803 lock(m_RunLock) 686 lock(m_RunLock)
804 { 687 {
805 CheckRunLockInvariants(true); 688 CheckRunLockInvariants(true);
806 689
807 /* 690 // No other thread should have transitioned it from RESETTING.
808 * No other thread should have transitioned it from RESETTING.
809 */
810 if(m_IState != XMRInstState.RESETTING) 691 if(m_IState != XMRInstState.RESETTING)
811 throw new Exception("bad state"); 692 throw new Exception("bad state");
812 693
813 /* 694 // 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.
815 */
816 m_IState = XMRInstState.IDLE; 695 m_IState = XMRInstState.IDLE;
817 696
818 /* 697 // Reset everything and queue up default's start_entry() event.
819 * Reset everything and queue up default's start_entry() event.
820 */
821 ClearQueue(); 698 ClearQueue();
822 ResetLocked("external Reset"); 699 ResetLocked("external Reset");
823 700
@@ -886,16 +763,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
886 m_SleepUntil = DateTime.MinValue; // not doing llSleep() 763 m_SleepUntil = DateTime.MinValue; // not doing llSleep()
887 m_ResetCount++; // has been reset once more 764 m_ResetCount++; // has been reset once more
888 765
889 /* 766 // Tell next call to 'default state_entry()' to reset all global
890 * Tell next call to 'default state_entry()' to reset all global 767 // vars to their initial values.
891 * vars to their initial values.
892 */
893 doGblInit = true; 768 doGblInit = true;
894 769
895 /* 770 // Set script to 'default' state and queue call to its
896 * Set script to 'default' state and queue call to its 771 // 'state_entry()' event handler.
897 * 'state_entry()' event handler.
898 */
899 m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; 772 m_RunOnePhase = "ResetLocked: posting default:state_entry() event";
900 stateCode = 0; 773 stateCode = 0;
901 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); 774 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0));
@@ -903,9 +776,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
903 zeroObjectArray, 776 zeroObjectArray,
904 zeroDetectParams)); 777 zeroDetectParams));
905 778
906 /* 779 // Tell CheckRun() to let script run.
907 * Tell CheckRun() to let script run.
908 */
909 suspendOnCheckRunHold = false; 780 suspendOnCheckRunHold = false;
910 suspendOnCheckRunTemp = false; 781 suspendOnCheckRunTemp = false;
911 m_RunOnePhase = "ResetLocked: reset complete"; 782 m_RunOnePhase = "ResetLocked: reset complete";
@@ -955,9 +826,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
955 } 826 }
956 m_CheckRunPhase = "entered"; 827 m_CheckRunPhase = "entered";
957 828
958 /* 829 // 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.
960 */
961 while(suspendOnCheckRunHold || suspendOnCheckRunTemp) 830 while(suspendOnCheckRunHold || suspendOnCheckRunTemp)
962 { 831 {
963 m_CheckRunPhase = "top of while"; 832 m_CheckRunPhase = "top of while";
@@ -997,10 +866,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
997 866
998 m_CheckRunPhase = "returning"; 867 m_CheckRunPhase = "returning";
999 868
1000 /* 869 // 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 870 // 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.
1003 */
1004 if(callMode != CallMode_NORMAL) 871 if(callMode != CallMode_NORMAL)
1005 throw new Exception("bad callMode " + callMode); 872 throw new Exception("bad callMode " + callMode);
1006 } 873 }