diff options
author | Melanie | 2013-01-16 15:47:55 +0000 |
---|---|---|
committer | Melanie | 2013-01-16 15:47:55 +0000 |
commit | 818254916cb562422b3a3301b9f35fafd64ee3fe (patch) | |
tree | e8655f6472b305d43a2f23059c375c90e7004a2b /OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |
parent | Merge branch 'master' into careminster (diff) | |
download | opensim-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.cs | 108 |
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 | } |