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.cs77
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)