diff options
Merge branch 'master' into careminster
Conflicts:
OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Instance')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index da2ef7b..6d56437 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -59,7 +59,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
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 | 60 | ||
61 | private IScriptEngine m_Engine; | 61 | private IScriptEngine m_Engine; |
62 | private IScriptWorkItem m_CurrentResult = null; | 62 | |
63 | /// <summary> | ||
64 | /// The current work item if an event for this script is running or waiting to run, | ||
65 | /// </summary> | ||
66 | /// <remarks> | ||
67 | /// Null if there is no running or waiting to run event. Must be changed only under an m_EventQueue lock. | ||
68 | /// </remarks> | ||
69 | private IScriptWorkItem m_CurrentWorkItem; | ||
70 | |||
63 | private Queue m_EventQueue = new Queue(32); | 71 | private Queue m_EventQueue = new Queue(32); |
64 | private bool m_RunEvents = false; | 72 | private bool m_RunEvents = false; |
65 | private UUID m_ItemID; | 73 | private UUID m_ItemID; |
@@ -158,7 +166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
158 | { | 166 | { |
159 | // Need to place ourselves back in a work item if there are events to process | 167 | // Need to place ourselves back in a work item if there are events to process |
160 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) | 168 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
161 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 169 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
162 | } | 170 | } |
163 | } | 171 | } |
164 | } | 172 | } |
@@ -528,8 +536,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
528 | 536 | ||
529 | if (m_EventQueue.Count > 0) | 537 | if (m_EventQueue.Count > 0) |
530 | { | 538 | { |
531 | if (m_CurrentResult == null) | 539 | if (m_CurrentWorkItem == null) |
532 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 540 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
533 | // else | 541 | // else |
534 | // m_log.Error("[Script] Tried to start a script that was already queued"); | 542 | // m_log.Error("[Script] Tried to start a script that was already queued"); |
535 | } | 543 | } |
@@ -541,49 +549,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
541 | // m_log.DebugFormat( | 549 | // m_log.DebugFormat( |
542 | // "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); | 550 | // "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); |
543 | 551 | ||
544 | IScriptWorkItem result; | 552 | IScriptWorkItem workItem; |
545 | 553 | ||
546 | lock (m_EventQueue) | 554 | lock (m_EventQueue) |
547 | { | 555 | { |
548 | if (!Running) | 556 | if (!Running) |
549 | return true; | 557 | return true; |
550 | 558 | ||
551 | if (m_CurrentResult == null) | 559 | // If we're not running or waiting to run an event then we can safely stop. |
560 | if (m_CurrentWorkItem == null) | ||
552 | { | 561 | { |
553 | m_RunEvents = false; | 562 | m_RunEvents = false; |
554 | return true; | 563 | return true; |
555 | } | 564 | } |
556 | 565 | ||
557 | if (m_CurrentResult.Cancel()) | 566 | // If we are waiting to run an event then we can try to cancel it. |
567 | if (m_CurrentWorkItem.Cancel()) | ||
558 | { | 568 | { |
559 | m_CurrentResult = null; | 569 | m_CurrentWorkItem = null; |
560 | m_RunEvents = false; | 570 | m_RunEvents = false; |
561 | return true; | 571 | return true; |
562 | } | 572 | } |
563 | 573 | ||
564 | result = m_CurrentResult; | 574 | workItem = m_CurrentWorkItem; |
565 | m_RunEvents = false; | 575 | m_RunEvents = false; |
566 | } | 576 | } |
567 | 577 | ||
568 | if (result.Wait(new TimeSpan((long)timeout * 100000))) | 578 | // Wait for the current event to complete. |
579 | if (workItem.Wait(new TimeSpan((long)timeout * 100000))) | ||
569 | { | 580 | { |
570 | return true; | 581 | return true; |
571 | } | 582 | } |
572 | 583 | ||
573 | lock (m_EventQueue) | 584 | lock (m_EventQueue) |
574 | { | 585 | { |
575 | result = m_CurrentResult; | 586 | workItem = m_CurrentWorkItem; |
576 | } | 587 | } |
577 | 588 | ||
578 | if (result == null) | 589 | if (workItem == null) |
579 | return true; | 590 | return true; |
580 | 591 | ||
592 | // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then | ||
593 | // forcibly abort the work item (this aborts the underlying thread). | ||
581 | if (!m_InSelfDelete) | 594 | if (!m_InSelfDelete) |
582 | result.Abort(); | 595 | { |
596 | // m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID); | ||
597 | |||
598 | workItem.Abort(); | ||
599 | } | ||
583 | 600 | ||
584 | lock (m_EventQueue) | 601 | lock (m_EventQueue) |
585 | { | 602 | { |
586 | m_CurrentResult = null; | 603 | m_CurrentWorkItem = null; |
587 | } | 604 | } |
588 | 605 | ||
589 | return true; | 606 | return true; |
@@ -605,6 +622,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
605 | throw new EventAbortException(); | 622 | throw new EventAbortException(); |
606 | } | 623 | } |
607 | 624 | ||
625 | /// <summary> | ||
626 | /// Post an event to this script instance. | ||
627 | /// </summary> | ||
628 | /// <remarks> | ||
629 | /// The request to run the event is sent | ||
630 | /// </remarks> | ||
631 | /// <param name="data"></param> | ||
608 | public void PostEvent(EventParams data) | 632 | public void PostEvent(EventParams data) |
609 | { | 633 | { |
610 | // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", | 634 | // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", |
@@ -671,9 +695,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
671 | 695 | ||
672 | m_EventQueue.Enqueue(data); | 696 | m_EventQueue.Enqueue(data); |
673 | 697 | ||
674 | if (m_CurrentResult == null) | 698 | if (m_CurrentWorkItem == null) |
675 | { | 699 | { |
676 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 700 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
677 | } | 701 | } |
678 | } | 702 | } |
679 | } | 703 | } |
@@ -698,11 +722,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
698 | { | 722 | { |
699 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) | 723 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
700 | { | 724 | { |
701 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 725 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
726 | { | ||
727 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); | ||
728 | } | ||
729 | else | ||
730 | { | ||
731 | m_CurrentWorkItem = null; | ||
732 | } | ||
733 | return 0; | ||
702 | } | 734 | } |
703 | else | 735 | else |
704 | { | 736 | { |
705 | m_CurrentResult = null; | 737 | m_CurrentWorkItem = null; |
706 | } | 738 | } |
707 | return 0; | 739 | return 0; |
708 | } | 740 | } |
@@ -825,15 +857,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
825 | } | 857 | } |
826 | } | 858 | } |
827 | 859 | ||
860 | |||
861 | // 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. | ||
828 | lock (m_EventQueue) | 863 | lock (m_EventQueue) |
829 | { | 864 | { |
830 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) | 865 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
831 | { | 866 | { |
832 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 867 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
833 | } | 868 | } |
834 | else | 869 | else |
835 | { | 870 | { |
836 | m_CurrentResult = null; | 871 | m_CurrentWorkItem = null; |
837 | } | 872 | } |
838 | } | 873 | } |
839 | 874 | ||
@@ -941,8 +976,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
941 | 976 | ||
942 | public void SaveState(string assembly) | 977 | public void SaveState(string assembly) |
943 | { | 978 | { |
944 | |||
945 | |||
946 | // If we're currently in an event, just tell it to save upon return | 979 | // If we're currently in an event, just tell it to save upon return |
947 | // | 980 | // |
948 | if (m_InEvent) | 981 | if (m_InEvent) |