aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
diff options
context:
space:
mode:
authorMelanie2013-01-16 15:47:55 +0000
committerMelanie2013-01-16 15:47:55 +0000
commit818254916cb562422b3a3301b9f35fafd64ee3fe (patch)
treee8655f6472b305d43a2f23059c375c90e7004a2b /OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
parentMerge branch 'master' into careminster (diff)
downloadopensim-SC-818254916cb562422b3a3301b9f35fafd64ee3fe.zip
opensim-SC-818254916cb562422b3a3301b9f35fafd64ee3fe.tar.gz
opensim-SC-818254916cb562422b3a3301b9f35fafd64ee3fe.tar.bz2
opensim-SC-818254916cb562422b3a3301b9f35fafd64ee3fe.tar.xz
JustinCC's core re-merge
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs108
1 files changed, 80 insertions, 28 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index ff4d130..a869a6a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -158,6 +158,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
158 158
159 public UUID AppDomain { get; set; } 159 public UUID AppDomain { get; set; }
160 160
161 public SceneObjectPart Part { get; private set; }
162
161 public string PrimName { get; private set; } 163 public string PrimName { get; private set; }
162 164
163 public string ScriptName { get; private set; } 165 public string ScriptName { get; private set; }
@@ -199,54 +201,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
199 201
200 public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; 202 public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute;
201 203
204 private bool m_coopTermination;
205
206 private EventWaitHandle m_coopSleepHandle;
207
202 public void ClearQueue() 208 public void ClearQueue()
203 { 209 {
204 m_TimerQueued = false; 210 m_TimerQueued = false;
205 EventQueue.Clear(); 211 EventQueue.Clear();
206 } 212 }
207 213
208 public ScriptInstance(IScriptEngine engine, SceneObjectPart part, 214 public ScriptInstance(
209 UUID itemID, UUID assetID, string assembly, 215 IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item,
210 AppDomain dom, string primName, string scriptName, 216 int startParam, bool postOnRez,
211 int startParam, bool postOnRez, StateSource stateSource, 217 int maxScriptQueue)
212 int maxScriptQueue)
213 { 218 {
214 State = "default"; 219 State = "default";
215 EventQueue = new Queue(32); 220 EventQueue = new Queue(32);
216 221
217 Engine = engine; 222 Engine = engine;
218 LocalID = part.LocalId; 223 Part = part;
219 ObjectID = part.UUID; 224 ScriptTask = item;
220 RootLocalID = part.ParentGroup.LocalId; 225
221 RootObjectID = part.ParentGroup.UUID; 226 // This is currently only here to allow regression tests to get away without specifying any inventory
222 ItemID = itemID; 227 // item when they are testing script logic that doesn't require an item.
223 AssetID = assetID; 228 if (ScriptTask != null)
224 PrimName = primName; 229 {
225 ScriptName = scriptName; 230 ScriptName = ScriptTask.Name;
226 m_Assembly = assembly; 231 ItemID = ScriptTask.ItemID;
232 AssetID = ScriptTask.AssetID;
233 }
234
235 PrimName = part.ParentGroup.Name;
227 StartParam = startParam; 236 StartParam = startParam;
228 m_MaxScriptQueue = maxScriptQueue; 237 m_MaxScriptQueue = maxScriptQueue;
229 m_stateSource = stateSource;
230 m_postOnRez = postOnRez; 238 m_postOnRez = postOnRez;
231 m_AttachedAvatar = part.ParentGroup.AttachedAvatar; 239 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
232 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; 240 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
233 241
234 if (part != null) 242 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
235 { 243 {
236 part.TaskInventory.LockItemsForRead(true); 244 m_coopTermination = true;
237 if (part.TaskInventory.ContainsKey(ItemID)) 245 m_coopSleepHandle = new AutoResetEvent(false);
238 {
239 ScriptTask = part.TaskInventory[ItemID];
240 }
241 part.TaskInventory.LockItemsForRead(false);
242 } 246 }
247 }
248
249 /// <summary>
250 /// Load the script from an assembly into an AppDomain.
251 /// </summary>
252 /// <param name='dom'></param>
253 /// <param name='assembly'></param>
254 /// <param name='stateSource'></param>
255 public void Load(AppDomain dom, string assembly, StateSource stateSource)
256 {
257 m_Assembly = assembly;
258 m_stateSource = stateSource;
243 259
244 ApiManager am = new ApiManager(); 260 ApiManager am = new ApiManager();
245 261
246 foreach (string api in am.GetApis()) 262 foreach (string api in am.GetApis())
247 { 263 {
248 m_Apis[api] = am.CreateApi(api); 264 m_Apis[api] = am.CreateApi(api);
249 m_Apis[api].Initialize(engine, part, ScriptTask); 265 m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle);
250 } 266 }
251 267
252 try 268 try
@@ -280,7 +296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
280 296
281// // m_log.Debug("[Script] Script instance created"); 297// // m_log.Debug("[Script] Script instance created");
282 298
283 part.SetScriptEvents(ItemID, 299 Part.SetScriptEvents(ItemID,
284 (int)m_Script.GetStateEventFlags(State)); 300 (int)m_Script.GetStateEventFlags(State));
285 } 301 }
286 catch (Exception e) 302 catch (Exception e)
@@ -322,7 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
322 338
323// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); 339// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName);
324 340
325 part.SetScriptEvents(ItemID, 341 Part.SetScriptEvents(ItemID,
326 (int)m_Script.GetStateEventFlags(State)); 342 (int)m_Script.GetStateEventFlags(State));
327 343
328 if (!Running) 344 if (!Running)
@@ -534,9 +550,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
534 } 550 }
535 551
536 // Wait for the current event to complete. 552 // Wait for the current event to complete.
537 if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) 553 if (!m_InSelfDelete)
538 { 554 {
539 return true; 555 if (!m_coopTermination)
556 {
557 // If we're not co-operative terminating then try and wait for the event to complete before stopping
558 if (workItem.Wait(new TimeSpan((long)timeout * 100000)))
559 return true;
560 }
561 else
562 {
563 m_log.DebugFormat(
564 "[SCRIPT INSTANCE]: Co-operatively stopping script {0} {1} in {2} {3}",
565 ScriptName, ItemID, PrimName, ObjectID);
566
567 // This will terminate the event on next handle check by the script.
568 m_coopSleepHandle.Set();
569
570 // For now, we will wait forever since the event should always cleanly terminate once LSL loop
571 // checking is implemented. May want to allow a shorter timeout option later.
572 if (workItem.Wait(TimeSpan.MaxValue))
573 {
574 m_log.DebugFormat(
575 "[SCRIPT INSTANCE]: Co-operatively stopped script {0} {1} in {2} {3}",
576 ScriptName, ItemID, PrimName, ObjectID);
577
578 return true;
579 }
580 }
540 } 581 }
541 582
542 lock (EventQueue) 583 lock (EventQueue)
@@ -549,6 +590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
549 590
550 // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then 591 // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then
551 // forcibly abort the work item (this aborts the underlying thread). 592 // forcibly abort the work item (this aborts the underlying thread).
593 // Co-operative termination should never reach this point.
552 if (!m_InSelfDelete) 594 if (!m_InSelfDelete)
553 { 595 {
554 m_log.DebugFormat( 596 m_log.DebugFormat(
@@ -796,7 +838,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
796 m_InEvent = false; 838 m_InEvent = false;
797 m_CurrentEvent = String.Empty; 839 m_CurrentEvent = String.Empty;
798 840
799 if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) 841 if ((!(e is TargetInvocationException)
842 || (!(e.InnerException is SelfDeleteException)
843 && !(e.InnerException is ScriptDeleteException)
844 && !(e.InnerException is ScriptCoopStopException)))
845 && !(e is ThreadAbortException))
800 { 846 {
801 try 847 try
802 { 848 {
@@ -846,6 +892,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 if (part != null) 892 if (part != null)
847 part.Inventory.RemoveInventoryItem(ItemID); 893 part.Inventory.RemoveInventoryItem(ItemID);
848 } 894 }
895 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
896 {
897 m_log.DebugFormat(
898 "[SCRIPT INSTANCE]: Script {0}.{1} in event {2}, state {3} stopped co-operatively.",
899 PrimName, ScriptName, data.EventName, State);
900 }
849 } 901 }
850 } 902 }
851 } 903 }