aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs66
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)