aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs82
1 files changed, 59 insertions, 23 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
index e610c36..c19d641 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
@@ -12,12 +12,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
12 /// <summary> 12 /// <summary>
13 /// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class 13 /// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class
14 /// </summary> 14 /// </summary>
15 public class EventQueueThreadClass 15 public class EventQueueThreadClass: iScriptEngineFunctionModule
16 { 16 {
17 /// <summary> 17 /// <summary>
18 /// How many ms to sleep if queue is empty 18 /// How many ms to sleep if queue is empty
19 /// </summary> 19 /// </summary>
20 private int nothingToDoSleepms;// = 50; 20 private int nothingToDoSleepms;// = 50;
21 private ThreadPriority MyThreadPriority;
21 22
22 public long LastExecutionStarted; 23 public long LastExecutionStarted;
23 public bool InExecution = false; 24 public bool InExecution = false;
@@ -26,25 +27,27 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
26 private EventQueueManager eventQueueManager; 27 private EventQueueManager eventQueueManager;
27 public Thread EventQueueThread; 28 public Thread EventQueueThread;
28 private static int ThreadCount = 0; 29 private static int ThreadCount = 0;
29 private ThreadPriority MyThreadPriority; 30
31 private string ScriptEngineName = "ScriptEngine.Common";
30 32
31 public EventQueueThreadClass(EventQueueManager eqm) 33 public EventQueueThreadClass(EventQueueManager eqm)
32 { 34 {
33 eventQueueManager = eqm; 35 eventQueueManager = eqm;
34 nothingToDoSleepms = eqm.m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50); 36 ReadConfig();
35 Start(); 37 Start();
36 } 38 }
37 39
38 ~EventQueueThreadClass() 40 ~EventQueueThreadClass()
39 { 41 {
40 Shutdown(); 42 Stop();
41 } 43 }
42 44
43 /// <summary> 45
44 /// Start thread 46 public void ReadConfig()
45 /// </summary>
46 private void Start()
47 { 47 {
48 ScriptEngineName = eventQueueManager.m_ScriptEngine.ScriptEngineName;
49 nothingToDoSleepms = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
50
48 // Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually 51 // Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
49 string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal"); 52 string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
50 switch (pri.ToLower()) 53 switch (pri.ToLower())
@@ -70,6 +73,19 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
70 break; 73 break;
71 } 74 }
72 75
76 // Now set that priority
77 if (EventQueueThread != null)
78 if (EventQueueThread.IsAlive)
79 EventQueueThread.Priority = MyThreadPriority;
80
81 }
82
83
84 /// <summary>
85 /// Start thread
86 /// </summary>
87 private void Start()
88 {
73 89
74 EventQueueThread = new Thread(EventQueueThreadLoop); 90 EventQueueThread = new Thread(EventQueueThreadLoop);
75 EventQueueThread.IsBackground = true; 91 EventQueueThread.IsBackground = true;
@@ -84,18 +100,20 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
84 ThreadCount++; 100 ThreadCount++;
85 } 101 }
86 102
87 public void Shutdown() 103 public void Stop()
88 { 104 {
105 PleaseShutdown = true; // Set shutdown flag
106 Thread.Sleep(100); // Wait a bit
89 if (EventQueueThread != null && EventQueueThread.IsAlive == true) 107 if (EventQueueThread != null && EventQueueThread.IsAlive == true)
90 { 108 {
91 try 109 try
92 { 110 {
93 EventQueueThread.Abort(); 111 EventQueueThread.Abort(); // Send abort
94 EventQueueThread.Join(); 112 EventQueueThread.Join(); // Wait for it
95 } 113 }
96 catch (Exception) 114 catch (Exception)
97 { 115 {
98 //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString()); 116 //myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Exception killing worker thread: " + e.ToString());
99 } 117 }
100 } 118 }
101 } 119 }
@@ -106,10 +124,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
106 /// </summary> 124 /// </summary>
107 private void EventQueueThreadLoop() 125 private void EventQueueThreadLoop()
108 { 126 {
109 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned"); 127 //myScriptEngine.m_logger.Verbose(ScriptEngineName, "EventQueueManager Worker thread spawned");
110 try 128 try
111 { 129 {
112 while (true) 130 while (true)
113 { 131 {
114 try 132 try
115 { 133 {
@@ -117,7 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
117 while (true) 135 while (true)
118 { 136 {
119 // Every now and then check if we should shut down 137 // Every now and then check if we should shut down
120 if (eventQueueManager.ThreadsToExit > 0) 138 if (PleaseShutdown || eventQueueManager.ThreadsToExit > 0)
121 { 139 {
122 // Someone should shut down, lets get exclusive lock 140 // Someone should shut down, lets get exclusive lock
123 lock (eventQueueManager.ThreadsToExitLock) 141 lock (eventQueueManager.ThreadsToExitLock)
@@ -125,9 +143,15 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
125 // Lets re-check in case someone grabbed it 143 // Lets re-check in case someone grabbed it
126 if (eventQueueManager.ThreadsToExit > 0) 144 if (eventQueueManager.ThreadsToExit > 0)
127 { 145 {
128 // We are go for shutdown 146 // Its crowded here so we'll shut down
129 eventQueueManager.ThreadsToExit--; 147 eventQueueManager.ThreadsToExit--;
130 Shutdown(); 148 Stop();
149 return;
150 }
151 else
152 {
153 // We have been asked to shut down
154 Stop();
131 return; 155 return;
132 } 156 }
133 } 157 }
@@ -139,6 +163,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
139 EventQueueManager.QueueItemStruct QIS = BlankQIS; 163 EventQueueManager.QueueItemStruct QIS = BlankQIS;
140 bool GotItem = false; 164 bool GotItem = false;
141 165
166 if (PleaseShutdown)
167 return;
168
142 if (eventQueueManager.eventQueue.Count == 0) 169 if (eventQueueManager.eventQueue.Count == 0)
143 { 170 {
144 // Nothing to do? Sleep a bit waiting for something to do 171 // Nothing to do? Sleep a bit waiting for something to do
@@ -147,7 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
147 else 174 else
148 { 175 {
149 // Something in queue, process 176 // Something in queue, process
150 //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); 177 //myScriptEngine.m_logger.Verbose(ScriptEngineName, "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
151 178
152 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD 179 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
153 lock (eventQueueManager.queueLock) 180 lock (eventQueueManager.queueLock)
@@ -179,7 +206,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
179 try 206 try
180 { 207 {
181#if DEBUG 208#if DEBUG
182 eventQueueManager.m_ScriptEngine.Log.Debug("ScriptEngine", 209 eventQueueManager.m_ScriptEngine.Log.Debug(ScriptEngineName,
183 "Executing event:\r\n" 210 "Executing event:\r\n"
184 + "QIS.localID: " + QIS.localID 211 + "QIS.localID: " + QIS.localID
185 + ", QIS.itemID: " + QIS.itemID 212 + ", QIS.itemID: " + QIS.itemID
@@ -235,7 +262,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
235 //else 262 //else
236 //{ 263 //{
237 // T oconsole 264 // T oconsole
238 eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine", 265 eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName,
239 "Unable to send text in-world:\r\n" + 266 "Unable to send text in-world:\r\n" +
240 text); 267 text);
241 } 268 }
@@ -260,19 +287,28 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
260 } 287 }
261 catch (ThreadAbortException tae) 288 catch (ThreadAbortException tae)
262 { 289 {
263 eventQueueManager.m_ScriptEngine.Log.Notice("ScriptEngine", "ThreadAbortException while executing function."); 290 eventQueueManager.m_ScriptEngine.Log.Notice(ScriptEngineName, "ThreadAbortException while executing function.");
264 } 291 }
265 catch (Exception e) 292 catch (Exception e)
266 { 293 {
267 eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine", "Exception in EventQueueThreadLoop: " + e.ToString()); 294 eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName, "Exception in EventQueueThreadLoop: " + e.ToString());
268 } 295 }
269 } // while 296 } // while
270 } // try 297 } // try
271 catch (ThreadAbortException) 298 catch (ThreadAbortException)
272 { 299 {
273 //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message); 300 //myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Worker thread killed: " + tae.Message);
274 } 301 }
275 } 302 }
276 303
304 /// <summary>
305 /// If set to true then threads and stuff should try to make a graceful exit
306 /// </summary>
307 public bool PleaseShutdown
308 {
309 get { return _PleaseShutdown; }
310 set { _PleaseShutdown = value; }
311 }
312 private bool _PleaseShutdown = false;
277 } 313 }
278} 314}