aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
authorMelanie2012-03-15 10:55:44 +0000
committerMelanie2012-03-15 10:55:44 +0000
commit897dc5e77eff911f9dd8870535c442f632d17662 (patch)
tree4bd4606e27f4c346f0267f6fc03c4541a2dc7046 /OpenSim/Region/ScriptEngine
parentAllow llTeleportAgent to teleport gods when not in god mode (diff)
parentRemove property/field duplication in ScriptInstance where it's unnecessary. (diff)
downloadopensim-SC_OLD-897dc5e77eff911f9dd8870535c442f632d17662.zip
opensim-SC_OLD-897dc5e77eff911f9dd8870535c442f632d17662.tar.gz
opensim-SC_OLD-897dc5e77eff911f9dd8870535c442f632d17662.tar.bz2
opensim-SC_OLD-897dc5e77eff911f9dd8870535c442f632d17662.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/Scene.cs OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs348
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs17
3 files changed, 154 insertions, 219 deletions
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index f00e41f..8762642 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -68,8 +68,16 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
68 /// </summary> 68 /// </summary>
69 bool Suspended { get; set; } 69 bool Suspended { get; set; }
70 70
71 /// <summary>
72 /// Is the script shutting down?
73 /// </summary>
71 bool ShuttingDown { get; set; } 74 bool ShuttingDown { get; set; }
75
76 /// <summary>
77 /// Script state
78 /// </summary>
72 string State { get; set; } 79 string State { get; set; }
80
73 IScriptEngine Engine { get; } 81 IScriptEngine Engine { get; }
74 UUID AppDomain { get; set; } 82 UUID AppDomain { get; set; }
75 string PrimName { get; } 83 string PrimName { get; }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6d56437..f40da01 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -57,44 +57,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
57 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
58 { 58 {
59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
60
61 private IScriptEngine m_Engine;
62 60
63 /// <summary> 61 /// <summary>
64 /// The current work item if an event for this script is running or waiting to run, 62 /// The current work item if an event for this script is running or waiting to run,
65 /// </summary> 63 /// </summary>
66 /// <remarks> 64 /// <remarks>
67 /// Null if there is no running or waiting to run event. Must be changed only under an m_EventQueue lock. 65 /// Null if there is no running or waiting to run event. Must be changed only under an EventQueue lock.
68 /// </remarks> 66 /// </remarks>
69 private IScriptWorkItem m_CurrentWorkItem; 67 private IScriptWorkItem m_CurrentWorkItem;
70 68
71 private Queue m_EventQueue = new Queue(32);
72 private bool m_RunEvents = false;
73 private UUID m_ItemID;
74 private uint m_LocalID;
75 private UUID m_ObjectID;
76 private UUID m_AssetID;
77 private IScript m_Script; 69 private IScript m_Script;
78 private UUID m_AppDomain;
79 private DetectParams[] m_DetectParams; 70 private DetectParams[] m_DetectParams;
80 private bool m_TimerQueued; 71 private bool m_TimerQueued;
81 private DateTime m_EventStart; 72 private DateTime m_EventStart;
82 private bool m_InEvent; 73 private bool m_InEvent;
83 private string m_PrimName;
84 private string m_ScriptName;
85 private string m_Assembly; 74 private string m_Assembly;
86 private int m_StartParam;
87 private string m_CurrentEvent = String.Empty; 75 private string m_CurrentEvent = String.Empty;
88 private bool m_InSelfDelete; 76 private bool m_InSelfDelete;
89 private int m_MaxScriptQueue; 77 private int m_MaxScriptQueue;
90 private bool m_SaveState = true; 78 private bool m_SaveState = true;
91 private bool m_ShuttingDown;
92 private int m_ControlEventsInQueue; 79 private int m_ControlEventsInQueue;
93 private int m_LastControlLevel; 80 private int m_LastControlLevel;
94 private bool m_CollisionInQueue; 81 private bool m_CollisionInQueue;
95 private TaskInventoryItem m_thisScriptTask; 82
96 // The following is for setting a minimum delay between events 83 // The following is for setting a minimum delay between events
97 private double m_minEventDelay; 84 private double m_minEventDelay;
85
98 private long m_eventDelayTicks; 86 private long m_eventDelayTicks;
99 private long m_nextEventTimeTicks; 87 private long m_nextEventTimeTicks;
100 private bool m_startOnInit = true; 88 private bool m_startOnInit = true;
@@ -105,21 +93,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
105 private UUID m_CurrentStateHash; 93 private UUID m_CurrentStateHash;
106 private UUID m_RegionID; 94 private UUID m_RegionID;
107 95
108 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> 96 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap { get; set; }
109 m_LineMap;
110
111 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
112 LineMap
113 {
114 get { return m_LineMap; }
115 set { m_LineMap = value; }
116 }
117 97
118 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); 98 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
119 99
120 // Script state
121 private string m_State = "default";
122
123 public Object[] PluginData = new Object[0]; 100 public Object[] PluginData = new Object[0];
124 101
125 /// <summary> 102 /// <summary>
@@ -142,11 +119,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
142 } 119 }
143 } 120 }
144 121
145 public bool Running 122 public bool Running { get; set; }
146 {
147 get { return m_RunEvents; }
148 set { m_RunEvents = value; }
149 }
150 123
151 public bool Suspended 124 public bool Suspended
152 { 125 {
@@ -162,11 +135,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
162 135
163 if (wasSuspended && !m_Suspended) 136 if (wasSuspended && !m_Suspended)
164 { 137 {
165 lock (m_EventQueue) 138 lock (EventQueue)
166 { 139 {
167 // Need to place ourselves back in a work item if there are events to process 140 // Need to place ourselves back in a work item if there are events to process
168 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 141 if (EventQueue.Count > 0 && Running && !ShuttingDown)
169 m_CurrentWorkItem = m_Engine.QueueEventHandler(this); 142 m_CurrentWorkItem = Engine.QueueEventHandler(this);
170 } 143 }
171 } 144 }
172 } 145 }
@@ -174,79 +147,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
174 } 147 }
175 private bool m_Suspended; 148 private bool m_Suspended;
176 149
177 public bool ShuttingDown 150 public bool ShuttingDown { get; set; }
178 {
179 get { return m_ShuttingDown; }
180 set { m_ShuttingDown = value; }
181 }
182 151
183 public string State 152 public string State { get; set; }
184 {
185 get { return m_State; }
186 set { m_State = value; }
187 }
188 153
189 public IScriptEngine Engine 154 public IScriptEngine Engine { get; private set; }
190 {
191 get { return m_Engine; }
192 }
193 155
194 public UUID AppDomain 156 public UUID AppDomain { get; set; }
195 {
196 get { return m_AppDomain; }
197 set { m_AppDomain = value; }
198 }
199 157
200 public string PrimName 158 public string PrimName { get; private set; }
201 {
202 get { return m_PrimName; }
203 }
204 159
205 public string ScriptName 160 public string ScriptName { get; private set; }
206 {
207 get { return m_ScriptName; }
208 }
209 161
210 public UUID ItemID 162 public UUID ItemID { get; private set; }
211 {
212 get { return m_ItemID; }
213 }
214 163
215 public UUID ObjectID 164 public UUID ObjectID { get; private set; }
216 {
217 get { return m_ObjectID; }
218 }
219 165
220 public uint LocalID 166 public uint LocalID { get; private set; }
221 {
222 get { return m_LocalID; }
223 }
224 167
225 public UUID AssetID 168 public UUID AssetID { get; private set; }
226 {
227 get { return m_AssetID; }
228 }
229 169
230 public Queue EventQueue 170 public Queue EventQueue { get; private set; }
231 {
232 get { return m_EventQueue; }
233 }
234 171
235 public void ClearQueue() 172 public int StartParam { get; set; }
236 {
237 m_TimerQueued = false;
238 m_EventQueue.Clear();
239 }
240 173
241 public int StartParam 174 public TaskInventoryItem ScriptTask { get; private set; }
242 {
243 get { return m_StartParam; }
244 set { m_StartParam = value; }
245 }
246 175
247 public TaskInventoryItem ScriptTask 176 public void ClearQueue()
248 { 177 {
249 get { return m_thisScriptTask; } 178 m_TimerQueued = false;
179 EventQueue.Clear();
250 } 180 }
251 181
252 public ScriptInstance(IScriptEngine engine, SceneObjectPart part, 182 public ScriptInstance(IScriptEngine engine, SceneObjectPart part,
@@ -255,16 +185,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
255 int startParam, bool postOnRez, StateSource stateSource, 185 int startParam, bool postOnRez, StateSource stateSource,
256 int maxScriptQueue) 186 int maxScriptQueue)
257 { 187 {
258 m_Engine = engine; 188 State = "default";
259 189 EventQueue = new Queue(32);
260 m_LocalID = part.LocalId; 190
261 m_ObjectID = part.UUID; 191 Engine = engine;
262 m_ItemID = itemID; 192 LocalID = part.LocalId;
263 m_AssetID = assetID; 193 ObjectID = part.UUID;
264 m_PrimName = primName; 194 ItemID = itemID;
265 m_ScriptName = scriptName; 195 AssetID = assetID;
196 PrimName = primName;
197 ScriptName = scriptName;
266 m_Assembly = assembly; 198 m_Assembly = assembly;
267 m_StartParam = startParam; 199 StartParam = startParam;
268 m_MaxScriptQueue = maxScriptQueue; 200 m_MaxScriptQueue = maxScriptQueue;
269 m_stateSource = stateSource; 201 m_stateSource = stateSource;
270 m_postOnRez = postOnRez; 202 m_postOnRez = postOnRez;
@@ -274,9 +206,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
274 if (part != null) 206 if (part != null)
275 { 207 {
276 part.TaskInventory.LockItemsForRead(true); 208 part.TaskInventory.LockItemsForRead(true);
277 if (part.TaskInventory.ContainsKey(m_ItemID)) 209 if (part.TaskInventory.ContainsKey(ItemID))
278 { 210 {
279 m_thisScriptTask = part.TaskInventory[m_ItemID]; 211 ScriptTask = part.TaskInventory[ItemID];
280 } 212 }
281 part.TaskInventory.LockItemsForRead(false); 213 part.TaskInventory.LockItemsForRead(false);
282 } 214 }
@@ -286,20 +218,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
286 foreach (string api in am.GetApis()) 218 foreach (string api in am.GetApis())
287 { 219 {
288 m_Apis[api] = am.CreateApi(api); 220 m_Apis[api] = am.CreateApi(api);
289 m_Apis[api].Initialize(engine, part, m_LocalID, itemID); 221 m_Apis[api].Initialize(engine, part, LocalID, itemID);
290 } 222 }
291 223
292 try 224 try
293 { 225 {
294 if (dom != System.AppDomain.CurrentDomain) 226 if (dom != System.AppDomain.CurrentDomain)
295 m_Script = (IScript)dom.CreateInstanceAndUnwrap( 227 m_Script = (IScript)dom.CreateInstanceAndUnwrap(
296 Path.GetFileNameWithoutExtension(assembly), 228 Path.GetFileNameWithoutExtension(assembly),
297 "SecondLife.Script"); 229 "SecondLife.Script");
298 else 230 else
299 m_Script = (IScript)Assembly.Load( 231 m_Script = (IScript)Assembly.Load(
300 Path.GetFileNameWithoutExtension(assembly)).CreateInstance( 232 Path.GetFileNameWithoutExtension(assembly)).CreateInstance(
301 "SecondLife.Script"); 233 "SecondLife.Script");
302
303 234
304 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 235 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
305 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 236 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
@@ -321,7 +252,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
321 252
322// // m_log.Debug("[Script] Script instance created"); 253// // m_log.Debug("[Script] Script instance created");
323 254
324 part.SetScriptEvents(m_ItemID, 255 part.SetScriptEvents(ItemID,
325 (int)m_Script.GetStateEventFlags(State)); 256 (int)m_Script.GetStateEventFlags(State));
326 } 257 }
327 catch (Exception e) 258 catch (Exception e)
@@ -336,7 +267,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
336 m_SaveState = true; 267 m_SaveState = true;
337 268
338 string savedState = Path.Combine(Path.GetDirectoryName(assembly), 269 string savedState = Path.Combine(Path.GetDirectoryName(assembly),
339 m_ItemID.ToString() + ".state"); 270 ItemID.ToString() + ".state");
340 if (File.Exists(savedState)) 271 if (File.Exists(savedState))
341 { 272 {
342 string xml = String.Empty; 273 string xml = String.Empty;
@@ -360,24 +291,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
360 291
361 ScriptSerializer.Deserialize(xml, this); 292 ScriptSerializer.Deserialize(xml, this);
362 293
363 AsyncCommandManager.CreateFromData(m_Engine, 294 AsyncCommandManager.CreateFromData(Engine,
364 m_LocalID, m_ItemID, m_ObjectID, 295 LocalID, ItemID, ObjectID,
365 PluginData); 296 PluginData);
366 297
367// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName); 298// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName);
368 299
369 part.SetScriptEvents(m_ItemID, 300 part.SetScriptEvents(ItemID,
370 (int)m_Script.GetStateEventFlags(State)); 301 (int)m_Script.GetStateEventFlags(State));
371 302
372 if (m_RunEvents && (!m_ShuttingDown)) 303 Running = false;
373 { 304
374 m_RunEvents = false; 305 if (ShuttingDown)
375 }
376 else
377 {
378 m_RunEvents = false;
379 m_startOnInit = false; 306 m_startOnInit = false;
380 }
381 307
382 // we get new rez events on sim restart, too 308 // we get new rez events on sim restart, too
383 // but if there is state, then we fire the change 309 // but if there is state, then we fire the change
@@ -386,7 +312,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
386 // We loaded state, don't force a re-save 312 // We loaded state, don't force a re-save
387 m_SaveState = false; 313 m_SaveState = false;
388 m_startedFromSavedState = true; 314 m_startedFromSavedState = true;
389
390 } 315 }
391 } 316 }
392 else 317 else
@@ -405,7 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
405 } 330 }
406// else 331// else
407// { 332// {
408// ScenePresence presence = m_Engine.World.GetScenePresence(part.OwnerID); 333// ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID);
409 334
410// if (presence != null && (!postOnRez)) 335// if (presence != null && (!postOnRez))
411// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); 336// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
@@ -423,7 +348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
423 if (m_postOnRez) 348 if (m_postOnRez)
424 { 349 {
425 PostEvent(new EventParams("on_rez", 350 PostEvent(new EventParams("on_rez",
426 new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0])); 351 new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
427 } 352 }
428 353
429 if (m_stateSource == StateSource.AttachedRez) 354 if (m_stateSource == StateSource.AttachedRez)
@@ -457,7 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
457 if (m_postOnRez) 382 if (m_postOnRez)
458 { 383 {
459 PostEvent(new EventParams("on_rez", 384 PostEvent(new EventParams("on_rez",
460 new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0])); 385 new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
461 } 386 }
462 387
463 if (m_stateSource == StateSource.AttachedRez) 388 if (m_stateSource == StateSource.AttachedRez)
@@ -471,27 +396,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
471 396
472 private void ReleaseControls() 397 private void ReleaseControls()
473 { 398 {
474 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(m_LocalID); 399 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
475 400
476 if (part != null) 401 if (part != null)
477 { 402 {
478 int permsMask; 403 int permsMask;
479 UUID permsGranter; 404 UUID permsGranter;
480 part.TaskInventory.LockItemsForRead(true); 405 part.TaskInventory.LockItemsForRead(true);
481 if (!part.TaskInventory.ContainsKey(m_ItemID)) 406 if (!part.TaskInventory.ContainsKey(ItemID))
482 { 407 {
483 part.TaskInventory.LockItemsForRead(false); 408 part.TaskInventory.LockItemsForRead(false);
484 return; 409 return;
485 } 410 }
486 permsGranter = part.TaskInventory[m_ItemID].PermsGranter; 411 permsGranter = part.TaskInventory[ItemID].PermsGranter;
487 permsMask = part.TaskInventory[m_ItemID].PermsMask; 412 permsMask = part.TaskInventory[ItemID].PermsMask;
488 part.TaskInventory.LockItemsForRead(false); 413 part.TaskInventory.LockItemsForRead(false);
489 414
490 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 415 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
491 { 416 {
492 ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter); 417 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
493 if (presence != null) 418 if (presence != null)
494 presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID); 419 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
495 } 420 }
496 } 421 }
497 } 422 }
@@ -499,13 +424,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
499 public void DestroyScriptInstance() 424 public void DestroyScriptInstance()
500 { 425 {
501 ReleaseControls(); 426 ReleaseControls();
502 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 427 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
503 } 428 }
504 429
505 public void RemoveState() 430 public void RemoveState()
506 { 431 {
507 string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), 432 string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly),
508 m_ItemID.ToString() + ".state"); 433 ItemID.ToString() + ".state");
509 434
510 try 435 try
511 { 436 {
@@ -518,7 +443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
518 443
519 public void VarDump(Dictionary<string, object> vars) 444 public void VarDump(Dictionary<string, object> vars)
520 { 445 {
521 // m_log.Info("Variable dump for script "+ m_ItemID.ToString()); 446 // m_log.Info("Variable dump for script "+ ItemID.ToString());
522 // foreach (KeyValuePair<string, object> v in vars) 447 // foreach (KeyValuePair<string, object> v in vars)
523 // { 448 // {
524 // m_log.Info("Variable: "+v.Key+" = "+v.Value.ToString()); 449 // m_log.Info("Variable: "+v.Key+" = "+v.Value.ToString());
@@ -527,17 +452,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
527 452
528 public void Start() 453 public void Start()
529 { 454 {
530 lock (m_EventQueue) 455 lock (EventQueue)
531 { 456 {
532 if (Running) 457 if (Running)
533 return; 458 return;
534 459
535 m_RunEvents = true; 460 Running = true;
536 461
537 if (m_EventQueue.Count > 0) 462 if (EventQueue.Count > 0)
538 { 463 {
539 if (m_CurrentWorkItem == null) 464 if (m_CurrentWorkItem == null)
540 m_CurrentWorkItem = m_Engine.QueueEventHandler(this); 465 m_CurrentWorkItem = Engine.QueueEventHandler(this);
541 // else 466 // else
542 // m_log.Error("[Script] Tried to start a script that was already queued"); 467 // m_log.Error("[Script] Tried to start a script that was already queued");
543 } 468 }
@@ -547,11 +472,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
547 public bool Stop(int timeout) 472 public bool Stop(int timeout)
548 { 473 {
549// m_log.DebugFormat( 474// m_log.DebugFormat(
550// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); 475// "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}",
476// ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks);
551 477
552 IScriptWorkItem workItem; 478 IScriptWorkItem workItem;
553 479
554 lock (m_EventQueue) 480 lock (EventQueue)
555 { 481 {
556 if (!Running) 482 if (!Running)
557 return true; 483 return true;
@@ -559,7 +485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
559 // If we're not running or waiting to run an event then we can safely stop. 485 // If we're not running or waiting to run an event then we can safely stop.
560 if (m_CurrentWorkItem == null) 486 if (m_CurrentWorkItem == null)
561 { 487 {
562 m_RunEvents = false; 488 Running = false;
563 return true; 489 return true;
564 } 490 }
565 491
@@ -567,21 +493,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
567 if (m_CurrentWorkItem.Cancel()) 493 if (m_CurrentWorkItem.Cancel())
568 { 494 {
569 m_CurrentWorkItem = null; 495 m_CurrentWorkItem = null;
570 m_RunEvents = false; 496 Running = false;
571 return true; 497 return true;
572 } 498 }
573 499
574 workItem = m_CurrentWorkItem; 500 workItem = m_CurrentWorkItem;
575 m_RunEvents = false; 501 Running = false;
576 } 502 }
577 503
578 // Wait for the current event to complete. 504 // Wait for the current event to complete.
579 if (workItem.Wait(new TimeSpan((long)timeout * 100000))) 505 if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000)))
580 { 506 {
581 return true; 507 return true;
582 } 508 }
583 509
584 lock (m_EventQueue) 510 lock (EventQueue)
585 { 511 {
586 workItem = m_CurrentWorkItem; 512 workItem = m_CurrentWorkItem;
587 } 513 }
@@ -593,12 +519,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
593 // forcibly abort the work item (this aborts the underlying thread). 519 // forcibly abort the work item (this aborts the underlying thread).
594 if (!m_InSelfDelete) 520 if (!m_InSelfDelete)
595 { 521 {
596// m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID); 522// m_log.ErrorFormat(
523// "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}",
524// ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks);
597 525
598 workItem.Abort(); 526 workItem.Abort();
599 } 527 }
600 528
601 lock (m_EventQueue) 529 lock (EventQueue)
602 { 530 {
603 m_CurrentWorkItem = null; 531 m_CurrentWorkItem = null;
604 } 532 }
@@ -632,7 +560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
632 public void PostEvent(EventParams data) 560 public void PostEvent(EventParams data)
633 { 561 {
634// m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", 562// m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}",
635// m_PrimName, m_ScriptName, data.EventName, m_State); 563// PrimName, ScriptName, data.EventName, State);
636 564
637 if (!Running) 565 if (!Running)
638 return; 566 return;
@@ -647,9 +575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
647 m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks; 575 m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks;
648 } 576 }
649 577
650 lock (m_EventQueue) 578 lock (EventQueue)
651 { 579 {
652 if (m_EventQueue.Count >= m_MaxScriptQueue) 580 if (EventQueue.Count >= m_MaxScriptQueue)
653 return; 581 return;
654 582
655 if (data.EventName == "timer") 583 if (data.EventName == "timer")
@@ -693,11 +621,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
693 m_CollisionInQueue = true; 621 m_CollisionInQueue = true;
694 } 622 }
695 623
696 m_EventQueue.Enqueue(data); 624 EventQueue.Enqueue(data);
697 625
698 if (m_CurrentWorkItem == null) 626 if (m_CurrentWorkItem == null)
699 { 627 {
700 m_CurrentWorkItem = m_Engine.QueueEventHandler(this); 628 m_CurrentWorkItem = Engine.QueueEventHandler(this);
701 } 629 }
702 } 630 }
703 } 631 }
@@ -709,28 +637,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
709 public object EventProcessor() 637 public object EventProcessor()
710 { 638 {
711 EventParams data = null; 639 EventParams data = null;
640 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
641 if (!Running)
642 return 0;
712 643
713// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 644// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
714 645
715 if (Suspended) 646 if (Suspended)
716 return 0; 647 return 0;
717 648
718 lock (m_EventQueue) 649 lock (EventQueue)
719 { 650 {
720 data = (EventParams) m_EventQueue.Dequeue(); 651 data = (EventParams) EventQueue.Dequeue();
721 if (data == null) // Shouldn't happen 652 if (data == null) // Shouldn't happen
722 { 653 {
723 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 654 if (EventQueue.Count > 0 && Running && !ShuttingDown)
724 { 655 {
725 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 656 m_CurrentWorkItem = Engine.QueueEventHandler(this);
726 {
727 m_CurrentWorkItem = m_Engine.QueueEventHandler(this);
728 }
729 else
730 {
731 m_CurrentWorkItem = null;
732 }
733 return 0;
734 } 657 }
735 else 658 else
736 { 659 {
@@ -760,28 +683,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
760 if (data.EventName == "state") // Hardcoded state change 683 if (data.EventName == "state") // Hardcoded state change
761 { 684 {
762 // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", 685 // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
763 // m_PrimName, m_ScriptName, data.Params[0].ToString()); 686 // PrimName, ScriptName, data.Params[0].ToString());
764 m_State = data.Params[0].ToString(); 687 State = data.Params[0].ToString();
765 AsyncCommandManager.RemoveScript(m_Engine, 688 AsyncCommandManager.RemoveScript(Engine,
766 m_LocalID, m_ItemID); 689 LocalID, ItemID);
767 690
768 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 691 SceneObjectPart part = Engine.World.GetSceneObjectPart(
769 m_LocalID); 692 LocalID);
770 if (part != null) 693 if (part != null)
771 { 694 {
772 part.SetScriptEvents(m_ItemID, 695 part.SetScriptEvents(ItemID,
773 (int)m_Script.GetStateEventFlags(State)); 696 (int)m_Script.GetStateEventFlags(State));
774 } 697 }
775 } 698 }
776 else 699 else
777 { 700 {
778 if (m_Engine.World.PipeEventsForScript(m_LocalID) || 701 if (Engine.World.PipeEventsForScript(LocalID) ||
779 data.EventName == "control") // Don't freeze avies! 702 data.EventName == "control") // Don't freeze avies!
780 { 703 {
781 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 704 SceneObjectPart part = Engine.World.GetSceneObjectPart(
782 m_LocalID); 705 LocalID);
783 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", 706 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
784 // m_PrimName, m_ScriptName, data.EventName, m_State); 707 // PrimName, ScriptName, data.EventName, State);
785 708
786 try 709 try
787 { 710 {
@@ -823,7 +746,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
823 746
824 if (text.Length > 1000) 747 if (text.Length > 1000)
825 text = text.Substring(0, 1000); 748 text = text.Substring(0, 1000);
826 m_Engine.World.SimChat(Utils.StringToBytes(text), 749 Engine.World.SimChat(Utils.StringToBytes(text),
827 ChatTypeEnum.DebugChannel, 2147483647, 750 ChatTypeEnum.DebugChannel, 2147483647,
828 part.AbsolutePosition, 751 part.AbsolutePosition,
829 part.Name, part.UUID, false); 752 part.Name, part.UUID, false);
@@ -845,26 +768,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
845 { 768 {
846 m_InSelfDelete = true; 769 m_InSelfDelete = true;
847 if (part != null) 770 if (part != null)
848 m_Engine.World.DeleteSceneObject(part.ParentGroup, false); 771 Engine.World.DeleteSceneObject(part.ParentGroup, false);
849 } 772 }
850 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 773 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
851 { 774 {
852 m_InSelfDelete = true; 775 m_InSelfDelete = true;
853 if (part != null) 776 if (part != null)
854 part.Inventory.RemoveInventoryItem(m_ItemID); 777 part.Inventory.RemoveInventoryItem(ItemID);
855 } 778 }
856 } 779 }
857 } 780 }
858 } 781 }
859 782
860
861 // If there are more events and we are currently running and not shutting down, then ask the 783 // If there are more events and we are currently running and not shutting down, then ask the
862 // script engine to run the next event. 784 // script engine to run the next event.
863 lock (m_EventQueue) 785 lock (EventQueue)
864 { 786 {
865 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 787 if (EventQueue.Count > 0 && Running && !ShuttingDown)
866 { 788 {
867 m_CurrentWorkItem = m_Engine.QueueEventHandler(this); 789 m_CurrentWorkItem = Engine.QueueEventHandler(this);
868 } 790 }
869 else 791 else
870 { 792 {
@@ -897,15 +819,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
897 ReleaseControls(); 819 ReleaseControls();
898 820
899 Stop(0); 821 Stop(0);
900 SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); 822 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
901 part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0; 823 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
902 part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero; 824 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
903 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 825 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
904 m_EventQueue.Clear(); 826 EventQueue.Clear();
905 m_Script.ResetVars(); 827 m_Script.ResetVars();
906 m_State = "default"; 828 State = "default";
907 829
908 part.SetScriptEvents(m_ItemID, 830 part.SetScriptEvents(ItemID,
909 (int)m_Script.GetStateEventFlags(State)); 831 (int)m_Script.GetStateEventFlags(State));
910 if (running) 832 if (running)
911 Start(); 833 Start();
@@ -923,16 +845,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
923 ReleaseControls(); 845 ReleaseControls();
924 846
925 m_Script.ResetVars(); 847 m_Script.ResetVars();
926 SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
927 part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
928 part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
929 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 851 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
930 852
931 m_EventQueue.Clear(); 853 EventQueue.Clear();
932 m_Script.ResetVars(); 854 m_Script.ResetVars();
933 m_State = "default"; 855 State = "default";
934 856
935 part.SetScriptEvents(m_ItemID, 857 part.SetScriptEvents(ItemID,
936 (int)m_Script.GetStateEventFlags(State)); 858 (int)m_Script.GetStateEventFlags(State));
937 859
938 if (m_CurrentEvent != "state_entry") 860 if (m_CurrentEvent != "state_entry")
@@ -984,7 +906,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
984 return; 906 return;
985 } 907 }
986 908
987 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); 909 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
988 910
989 string xml = ScriptSerializer.Serialize(this); 911 string xml = ScriptSerializer.Serialize(this);
990 912
@@ -996,7 +918,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
996 { 918 {
997 try 919 try
998 { 920 {
999 FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")); 921 FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state"));
1000 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); 922 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1001 Byte[] buf = enc.GetBytes(xml); 923 Byte[] buf = enc.GetBytes(xml);
1002 fs.Write(buf, 0, buf.Length); 924 fs.Write(buf, 0, buf.Length);
@@ -1006,7 +928,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1006 { 928 {
1007 // m_log.Error("Unable to save xml\n"+e.ToString()); 929 // m_log.Error("Unable to save xml\n"+e.ToString());
1008 } 930 }
1009 //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"))) 931 //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")))
1010 //{ 932 //{
1011 // throw new Exception("Completed persistence save, but no file was created"); 933 // throw new Exception("Completed persistence save, but no file was created");
1012 //} 934 //}
@@ -1023,7 +945,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1023 945
1024 public override string ToString() 946 public override string ToString()
1025 { 947 {
1026 return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName); 948 return String.Format("{0} {1} on {2}", ScriptName, ItemID, PrimName);
1027 } 949 }
1028 950
1029 string FormatException(Exception e) 951 string FormatException(Exception e)
@@ -1091,7 +1013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1091 1013
1092 // Force an update of the in-memory plugin data 1014 // Force an update of the in-memory plugin data
1093 // 1015 //
1094 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); 1016 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
1095 1017
1096 return ScriptSerializer.Serialize(this); 1018 return ScriptSerializer.Serialize(this);
1097 } 1019 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 1d3ba6c..ee5f519 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -244,12 +244,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
244 get { return m_ConfigSource; } 244 get { return m_ConfigSource; }
245 } 245 }
246 246
247 /// <summary>
248 /// Event fired after the script engine has finished removing a script.
249 /// </summary>
247 public event ScriptRemoved OnScriptRemoved; 250 public event ScriptRemoved OnScriptRemoved;
251
252 /// <summary>
253 /// Event fired after the script engine has finished removing a script from an object.
254 /// </summary>
248 public event ObjectRemoved OnObjectRemoved; 255 public event ObjectRemoved OnObjectRemoved;
249 256
250 //
251 // IRegionModule functions
252 //
253 public void Initialise(IConfigSource configSource) 257 public void Initialise(IConfigSource configSource)
254 { 258 {
255 if (configSource.Configs["XEngine"] == null) 259 if (configSource.Configs["XEngine"] == null)
@@ -1199,7 +1203,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1199 m_Scripts.Remove(itemID); 1203 m_Scripts.Remove(itemID);
1200 lockScriptsForWrite(false); 1204 lockScriptsForWrite(false);
1201 instance.ClearQueue(); 1205 instance.ClearQueue();
1202 instance.Stop(0); 1206
1207 // Give the script some time to finish processing its last event. Simply aborting the script thread can
1208 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1209 instance.Stop(1000);
1203 1210
1204// bool objectRemoved = false; 1211// bool objectRemoved = false;
1205 1212
@@ -1231,8 +1238,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1231 UnloadAppDomain(instance.AppDomain); 1238 UnloadAppDomain(instance.AppDomain);
1232 } 1239 }
1233 1240
1234 instance = null;
1235
1236 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1241 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1237 if (handlerObjectRemoved != null) 1242 if (handlerObjectRemoved != null)
1238 { 1243 {