diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 4010167..b840730 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -58,7 +58,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
58 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 58 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
59 | 59 | ||
60 | private IScriptEngine m_Engine; | 60 | private IScriptEngine m_Engine; |
61 | private IScriptWorkItem m_CurrentResult = null; | 61 | |
62 | /// <summary> | ||
63 | /// The current work item if an event for this script is running or waiting to run, | ||
64 | /// </summary> | ||
65 | /// <remarks> | ||
66 | /// Null if there is no running or waiting to run event. Must be changed only under an m_EventQueue lock. | ||
67 | /// </remarks> | ||
68 | private IScriptWorkItem m_CurrentWorkItem; | ||
69 | |||
62 | private Queue m_EventQueue = new Queue(32); | 70 | private Queue m_EventQueue = new Queue(32); |
63 | private bool m_RunEvents = false; | 71 | private bool m_RunEvents = false; |
64 | private UUID m_ItemID; | 72 | private UUID m_ItemID; |
@@ -157,7 +165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
157 | { | 165 | { |
158 | // Need to place ourselves back in a work item if there are events to process | 166 | // Need to place ourselves back in a work item if there are events to process |
159 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) | 167 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
160 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 168 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
161 | } | 169 | } |
162 | } | 170 | } |
163 | } | 171 | } |
@@ -527,8 +535,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
527 | 535 | ||
528 | if (m_EventQueue.Count > 0) | 536 | if (m_EventQueue.Count > 0) |
529 | { | 537 | { |
530 | if (m_CurrentResult == null) | 538 | if (m_CurrentWorkItem == null) |
531 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 539 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
532 | // else | 540 | // else |
533 | // m_log.Error("[Script] Tried to start a script that was already queued"); | 541 | // m_log.Error("[Script] Tried to start a script that was already queued"); |
534 | } | 542 | } |
@@ -540,52 +548,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
540 | // m_log.DebugFormat( | 548 | // m_log.DebugFormat( |
541 | // "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); | 549 | // "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); |
542 | 550 | ||
543 | IScriptWorkItem result; | 551 | IScriptWorkItem workItem; |
544 | 552 | ||
545 | lock (m_EventQueue) | 553 | lock (m_EventQueue) |
546 | { | 554 | { |
547 | if (!Running) | 555 | if (!Running) |
548 | return true; | 556 | return true; |
549 | 557 | ||
550 | if (m_CurrentResult == null) | 558 | // If we're not running or waiting to run an event then we can safely stop. |
559 | if (m_CurrentWorkItem == null) | ||
551 | { | 560 | { |
552 | m_RunEvents = false; | 561 | m_RunEvents = false; |
553 | return true; | 562 | return true; |
554 | } | 563 | } |
555 | 564 | ||
556 | if (m_CurrentResult.Cancel()) | 565 | // If we are waiting to run an event then we can try to cancel it. |
566 | if (m_CurrentWorkItem.Cancel()) | ||
557 | { | 567 | { |
558 | m_CurrentResult = null; | 568 | m_CurrentWorkItem = null; |
559 | m_RunEvents = false; | 569 | m_RunEvents = false; |
560 | return true; | 570 | return true; |
561 | } | 571 | } |
562 | 572 | ||
563 | result = m_CurrentResult; | 573 | workItem = m_CurrentWorkItem; |
564 | m_RunEvents = false; | 574 | m_RunEvents = false; |
565 | } | 575 | } |
566 | 576 | ||
567 | if (result.Wait(new TimeSpan((long)timeout * 100000))) | 577 | // Wait for the current event to complete. |
578 | if (workItem.Wait(new TimeSpan((long)timeout * 100000))) | ||
568 | { | 579 | { |
569 | return true; | 580 | return true; |
570 | } | 581 | } |
571 | 582 | ||
572 | lock (m_EventQueue) | 583 | lock (m_EventQueue) |
573 | { | 584 | { |
574 | result = m_CurrentResult; | 585 | workItem = m_CurrentWorkItem; |
575 | } | 586 | } |
576 | 587 | ||
577 | if (result == null) | 588 | if (workItem == null) |
578 | return true; | 589 | return true; |
579 | 590 | ||
591 | // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then | ||
592 | // forcibly abort the work item (this aborts the underlying thread). | ||
580 | if (!m_InSelfDelete) | 593 | if (!m_InSelfDelete) |
581 | { | 594 | { |
582 | // m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID); | 595 | // m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID); |
583 | result.Abort(); | 596 | |
597 | workItem.Abort(); | ||
584 | } | 598 | } |
585 | 599 | ||
586 | lock (m_EventQueue) | 600 | lock (m_EventQueue) |
587 | { | 601 | { |
588 | m_CurrentResult = null; | 602 | m_CurrentWorkItem = null; |
589 | } | 603 | } |
590 | 604 | ||
591 | return true; | 605 | return true; |
@@ -606,6 +620,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
606 | throw new EventAbortException(); | 620 | throw new EventAbortException(); |
607 | } | 621 | } |
608 | 622 | ||
623 | /// <summary> | ||
624 | /// Post an event to this script instance. | ||
625 | /// </summary> | ||
626 | /// <remarks> | ||
627 | /// The request to run the event is sent | ||
628 | /// </remarks> | ||
629 | /// <param name="data"></param> | ||
609 | public void PostEvent(EventParams data) | 630 | public void PostEvent(EventParams data) |
610 | { | 631 | { |
611 | // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", | 632 | // m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", |
@@ -672,9 +693,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
672 | 693 | ||
673 | m_EventQueue.Enqueue(data); | 694 | m_EventQueue.Enqueue(data); |
674 | 695 | ||
675 | if (m_CurrentResult == null) | 696 | if (m_CurrentWorkItem == null) |
676 | { | 697 | { |
677 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 698 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
678 | } | 699 | } |
679 | } | 700 | } |
680 | } | 701 | } |
@@ -701,11 +722,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
701 | { | 722 | { |
702 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) | 723 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
703 | { | 724 | { |
704 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 725 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
705 | } | 726 | } |
706 | else | 727 | else |
707 | { | 728 | { |
708 | m_CurrentResult = null; | 729 | m_CurrentWorkItem = null; |
709 | } | 730 | } |
710 | return 0; | 731 | return 0; |
711 | } | 732 | } |
@@ -825,15 +846,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
825 | } | 846 | } |
826 | } | 847 | } |
827 | 848 | ||
849 | |||
850 | // If there are more events and we are currently running and not shutting down, then ask the | ||
851 | // script engine to run the next event. | ||
828 | lock (m_EventQueue) | 852 | lock (m_EventQueue) |
829 | { | 853 | { |
830 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) | 854 | if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) |
831 | { | 855 | { |
832 | m_CurrentResult = m_Engine.QueueEventHandler(this); | 856 | m_CurrentWorkItem = m_Engine.QueueEventHandler(this); |
833 | } | 857 | } |
834 | else | 858 | else |
835 | { | 859 | { |
836 | m_CurrentResult = null; | 860 | m_CurrentWorkItem = null; |
837 | } | 861 | } |
838 | } | 862 | } |
839 | 863 | ||
@@ -943,8 +967,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
943 | 967 | ||
944 | public void SaveState(string assembly) | 968 | public void SaveState(string assembly) |
945 | { | 969 | { |
946 | |||
947 | |||
948 | // If we're currently in an event, just tell it to save upon return | 970 | // If we're currently in an event, just tell it to save upon return |
949 | // | 971 | // |
950 | if (m_InEvent) | 972 | if (m_InEvent) |