aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
authorJeff Ames2008-02-02 07:13:37 +0000
committerJeff Ames2008-02-02 07:13:37 +0000
commitb1a6f4821b650acf5523d8d7114a8f5c122dedcb (patch)
treeab37383c2c71a3f36acd1a4f69295f4068dc7011 /OpenSim/Region/ScriptEngine
parentHopefully fixed MySQL DB crash on startup issue (so we can remove 3 sec wait). (diff)
downloadopensim-SC-b1a6f4821b650acf5523d8d7114a8f5c122dedcb.zip
opensim-SC-b1a6f4821b650acf5523d8d7114a8f5c122dedcb.tar.gz
opensim-SC-b1a6f4821b650acf5523d8d7114a8f5c122dedcb.tar.bz2
opensim-SC-b1a6f4821b650acf5523d8d7114a8f5c122dedcb.tar.xz
Updated svn properties.
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs624
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs628
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs326
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs22
4 files changed, 800 insertions, 800 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
index 5ec8f50..c8b1256 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
@@ -1,313 +1,313 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Threading; 31using System.Threading;
32using libsecondlife; 32using libsecondlife;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Modules; 34using OpenSim.Region.Environment.Modules;
35 35
36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
37{ 37{
38 /// <summary> 38 /// <summary>
39 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. 39 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
40 /// </summary> 40 /// </summary>
41 public class AsyncLSLCommandManager : iScriptEngineFunctionModule 41 public class AsyncLSLCommandManager : iScriptEngineFunctionModule
42 { 42 {
43 private Thread cmdHandlerThread; 43 private Thread cmdHandlerThread;
44 private int cmdHandlerThreadCycleSleepms; 44 private int cmdHandlerThreadCycleSleepms;
45 45
46 private ScriptEngine m_ScriptEngine; 46 private ScriptEngine m_ScriptEngine;
47 47
48 public AsyncLSLCommandManager(ScriptEngine _ScriptEngine) 48 public AsyncLSLCommandManager(ScriptEngine _ScriptEngine)
49 { 49 {
50 m_ScriptEngine = _ScriptEngine; 50 m_ScriptEngine = _ScriptEngine;
51 ReadConfig(); 51 ReadConfig();
52 52
53 // Start the thread that will be doing the work 53 // Start the thread that will be doing the work
54 cmdHandlerThread = new Thread(CmdHandlerThreadLoop); 54 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
55 cmdHandlerThread.Name = "CmdHandlerThread"; 55 cmdHandlerThread.Name = "CmdHandlerThread";
56 cmdHandlerThread.Priority = ThreadPriority.BelowNormal; 56 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
57 cmdHandlerThread.IsBackground = true; 57 cmdHandlerThread.IsBackground = true;
58 cmdHandlerThread.Start(); 58 cmdHandlerThread.Start();
59 } 59 }
60 60
61 public void ReadConfig() 61 public void ReadConfig()
62 { 62 {
63 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 50); 63 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 50);
64 } 64 }
65 65
66 66
67 ~AsyncLSLCommandManager() 67 ~AsyncLSLCommandManager()
68 { 68 {
69 // Shut down thread 69 // Shut down thread
70 try 70 try
71 { 71 {
72 if (cmdHandlerThread != null) 72 if (cmdHandlerThread != null)
73 { 73 {
74 if (cmdHandlerThread.IsAlive == true) 74 if (cmdHandlerThread.IsAlive == true)
75 { 75 {
76 cmdHandlerThread.Abort(); 76 cmdHandlerThread.Abort();
77 cmdHandlerThread.Join(); 77 cmdHandlerThread.Join();
78 } 78 }
79 } 79 }
80 } 80 }
81 catch 81 catch
82 { 82 {
83 } 83 }
84 } 84 }
85 85
86 private void CmdHandlerThreadLoop() 86 private void CmdHandlerThreadLoop()
87 { 87 {
88 while (true) 88 while (true)
89 { 89 {
90 // Check timers 90 // Check timers
91 CheckTimerEvents(); 91 CheckTimerEvents();
92 Thread.Sleep(25); 92 Thread.Sleep(25);
93 // Check HttpRequests 93 // Check HttpRequests
94 CheckHttpRequests(); 94 CheckHttpRequests();
95 Thread.Sleep(25); 95 Thread.Sleep(25);
96 // Check XMLRPCRequests 96 // Check XMLRPCRequests
97 CheckXMLRPCRequests(); 97 CheckXMLRPCRequests();
98 Thread.Sleep(25); 98 Thread.Sleep(25);
99 // Check Listeners 99 // Check Listeners
100 CheckListeners(); 100 CheckListeners();
101 Thread.Sleep(25); 101 Thread.Sleep(25);
102 102
103 // Sleep before next cycle 103 // Sleep before next cycle
104 //Thread.Sleep(cmdHandlerThreadCycleSleepms); 104 //Thread.Sleep(cmdHandlerThreadCycleSleepms);
105 } 105 }
106 } 106 }
107 107
108 /// <summary> 108 /// <summary>
109 /// Remove a specific script (and all its pending commands) 109 /// Remove a specific script (and all its pending commands)
110 /// </summary> 110 /// </summary>
111 /// <param name="m_localID"></param> 111 /// <param name="m_localID"></param>
112 /// <param name="m_itemID"></param> 112 /// <param name="m_itemID"></param>
113 public void RemoveScript(uint localID, LLUUID itemID) 113 public void RemoveScript(uint localID, LLUUID itemID)
114 { 114 {
115 // Remove a specific script 115 // Remove a specific script
116 116
117 // Remove from: Timers 117 // Remove from: Timers
118 UnSetTimerEvents(localID, itemID); 118 UnSetTimerEvents(localID, itemID);
119 // Remove from: HttpRequest 119 // Remove from: HttpRequest
120 IHttpRequests iHttpReq = 120 IHttpRequests iHttpReq =
121 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); 121 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
122 iHttpReq.StopHttpRequest(localID, itemID); 122 iHttpReq.StopHttpRequest(localID, itemID);
123 } 123 }
124 124
125 #region TIMER 125 #region TIMER
126 126
127 // 127 //
128 // TIMER 128 // TIMER
129 // 129 //
130 private class TimerClass 130 private class TimerClass
131 { 131 {
132 public uint localID; 132 public uint localID;
133 public LLUUID itemID; 133 public LLUUID itemID;
134 public double interval; 134 public double interval;
135 public DateTime next; 135 public DateTime next;
136 } 136 }
137 137
138 private List<TimerClass> Timers = new List<TimerClass>(); 138 private List<TimerClass> Timers = new List<TimerClass>();
139 private object TimerListLock = new object(); 139 private object TimerListLock = new object();
140 140
141 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) 141 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
142 { 142 {
143 Console.WriteLine("SetTimerEvent"); 143 Console.WriteLine("SetTimerEvent");
144 144
145 // Always remove first, in case this is a re-set 145 // Always remove first, in case this is a re-set
146 UnSetTimerEvents(m_localID, m_itemID); 146 UnSetTimerEvents(m_localID, m_itemID);
147 if (sec == 0) // Disabling timer 147 if (sec == 0) // Disabling timer
148 return; 148 return;
149 149
150 // Add to timer 150 // Add to timer
151 TimerClass ts = new TimerClass(); 151 TimerClass ts = new TimerClass();
152 ts.localID = m_localID; 152 ts.localID = m_localID;
153 ts.itemID = m_itemID; 153 ts.itemID = m_itemID;
154 ts.interval = sec; 154 ts.interval = sec;
155 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 155 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
156 lock (TimerListLock) 156 lock (TimerListLock)
157 { 157 {
158 Timers.Add(ts); 158 Timers.Add(ts);
159 } 159 }
160 } 160 }
161 161
162 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) 162 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
163 { 163 {
164 // Remove from timer 164 // Remove from timer
165 lock (TimerListLock) 165 lock (TimerListLock)
166 { 166 {
167 List<TimerClass> NewTimers = new List<TimerClass>(); 167 List<TimerClass> NewTimers = new List<TimerClass>();
168 foreach (TimerClass ts in Timers) 168 foreach (TimerClass ts in Timers)
169 { 169 {
170 if (ts.localID != m_localID && ts.itemID != m_itemID) 170 if (ts.localID != m_localID && ts.itemID != m_itemID)
171 { 171 {
172 NewTimers.Add(ts); 172 NewTimers.Add(ts);
173 } 173 }
174 } 174 }
175 Timers.Clear(); 175 Timers.Clear();
176 Timers = NewTimers; 176 Timers = NewTimers;
177 } 177 }
178 } 178 }
179 179
180 public void CheckTimerEvents() 180 public void CheckTimerEvents()
181 { 181 {
182 // Nothing to do here? 182 // Nothing to do here?
183 if (Timers.Count == 0) 183 if (Timers.Count == 0)
184 return; 184 return;
185 185
186 lock (TimerListLock) 186 lock (TimerListLock)
187 { 187 {
188 // Go through all timers 188 // Go through all timers
189 foreach (TimerClass ts in Timers) 189 foreach (TimerClass ts in Timers)
190 { 190 {
191 // Time has passed? 191 // Time has passed?
192 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) 192 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
193 { 193 {
194 // Add it to queue 194 // Add it to queue
195 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull, 195 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull,
196 new object[] {}); 196 new object[] {});
197 // set next interval 197 // set next interval
198 198
199 199
200 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 200 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
201 } 201 }
202 } 202 }
203 } // lock 203 } // lock
204 } 204 }
205 205
206 #endregion 206 #endregion
207 207
208 #region HTTP REQUEST 208 #region HTTP REQUEST
209 209
210 public void CheckHttpRequests() 210 public void CheckHttpRequests()
211 { 211 {
212 if (m_ScriptEngine.World == null) 212 if (m_ScriptEngine.World == null)
213 return; 213 return;
214 214
215 IHttpRequests iHttpReq = 215 IHttpRequests iHttpReq =
216 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); 216 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
217 217
218 HttpRequestClass httpInfo = null; 218 HttpRequestClass httpInfo = null;
219 219
220 if (iHttpReq != null) 220 if (iHttpReq != null)
221 httpInfo = iHttpReq.GetNextCompletedRequest(); 221 httpInfo = iHttpReq.GetNextCompletedRequest();
222 222
223 while (httpInfo != null) 223 while (httpInfo != null)
224 { 224 {
225 //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status); 225 //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
226 226
227 // Deliver data to prim's remote_data handler 227 // Deliver data to prim's remote_data handler
228 // 228 //
229 // TODO: Returning null for metadata, since the lsl function 229 // TODO: Returning null for metadata, since the lsl function
230 // only returns the byte for HTTP_BODY_TRUNCATED, which is not 230 // only returns the byte for HTTP_BODY_TRUNCATED, which is not
231 // implemented here yet anyway. Should be fixed if/when maxsize 231 // implemented here yet anyway. Should be fixed if/when maxsize
232 // is supported 232 // is supported
233 233
234 object[] resobj = new object[] 234 object[] resobj = new object[]
235 { 235 {
236 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body 236 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
237 }; 237 };
238 238
239 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 239 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
240 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj 240 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
241 ); 241 );
242 242
243 httpInfo.Stop(); 243 httpInfo.Stop();
244 httpInfo = null; 244 httpInfo = null;
245 245
246 httpInfo = iHttpReq.GetNextCompletedRequest(); 246 httpInfo = iHttpReq.GetNextCompletedRequest();
247 } 247 }
248 } 248 }
249 249
250 #endregion 250 #endregion
251 251
252 public void CheckXMLRPCRequests() 252 public void CheckXMLRPCRequests()
253 { 253 {
254 if (m_ScriptEngine.World == null) 254 if (m_ScriptEngine.World == null)
255 return; 255 return;
256 256
257 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 257 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
258 258
259 if (xmlrpc != null) 259 if (xmlrpc != null)
260 { 260 {
261 while (xmlrpc.hasRequests()) 261 while (xmlrpc.hasRequests())
262 { 262 {
263 RPCRequestInfo rInfo = xmlrpc.GetNextRequest(); 263 RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
264 //Console.WriteLine("PICKED REQUEST"); 264 //Console.WriteLine("PICKED REQUEST");
265 265
266 //Deliver data to prim's remote_data handler 266 //Deliver data to prim's remote_data handler
267 object[] resobj = new object[] 267 object[] resobj = new object[]
268 { 268 {
269 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty, 269 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty,
270 rInfo.GetIntValue(), 270 rInfo.GetIntValue(),
271 rInfo.GetStrVal() 271 rInfo.GetStrVal()
272 }; 272 };
273 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 273 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
274 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj 274 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
275 ); 275 );
276 } 276 }
277 } 277 }
278 } 278 }
279 279
280 public void CheckListeners() 280 public void CheckListeners()
281 { 281 {
282 if (m_ScriptEngine.World == null) 282 if (m_ScriptEngine.World == null)
283 return; 283 return;
284 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 284 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
285 285
286 while (comms.HasMessages()) 286 while (comms.HasMessages())
287 { 287 {
288 ListenerInfo lInfo = comms.GetNextMessage(); 288 ListenerInfo lInfo = comms.GetNextMessage();
289 289
290 //Deliver data to prim's listen handler 290 //Deliver data to prim's listen handler
291 object[] resobj = new object[] 291 object[] resobj = new object[]
292 { 292 {
293 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() 293 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
294 }; 294 };
295 295
296 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 296 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
297 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj 297 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
298 ); 298 );
299 } 299 }
300 } 300 }
301 301
302 /// <summary> 302 /// <summary>
303 /// If set to true then threads and stuff should try to make a graceful exit 303 /// If set to true then threads and stuff should try to make a graceful exit
304 /// </summary> 304 /// </summary>
305 public bool PleaseShutdown 305 public bool PleaseShutdown
306 { 306 {
307 get { return _PleaseShutdown; } 307 get { return _PleaseShutdown; }
308 set { _PleaseShutdown = value; } 308 set { _PleaseShutdown = value; }
309 } 309 }
310 private bool _PleaseShutdown = false; 310 private bool _PleaseShutdown = false;
311 311
312 } 312 }
313} \ No newline at end of file 313} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
index c19d641..b239965 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
@@ -1,314 +1,314 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using System.Threading; 4using System.Threading;
5using libsecondlife; 5using libsecondlife;
6using Nini.Config; 6using Nini.Config;
7using OpenSim.Framework; 7using OpenSim.Framework;
8using OpenSim.Region.Environment.Scenes.Scripting; 8using OpenSim.Region.Environment.Scenes.Scripting;
9 9
10namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 10namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
11{ 11{
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: iScriptEngineFunctionModule 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 private ThreadPriority MyThreadPriority;
22 22
23 public long LastExecutionStarted; 23 public long LastExecutionStarted;
24 public bool InExecution = false; 24 public bool InExecution = false;
25 public bool KillCurrentScript = false; 25 public bool KillCurrentScript = false;
26 26
27 private EventQueueManager eventQueueManager; 27 private EventQueueManager eventQueueManager;
28 public Thread EventQueueThread; 28 public Thread EventQueueThread;
29 private static int ThreadCount = 0; 29 private static int ThreadCount = 0;
30 30
31 private string ScriptEngineName = "ScriptEngine.Common"; 31 private string ScriptEngineName = "ScriptEngine.Common";
32 32
33 public EventQueueThreadClass(EventQueueManager eqm) 33 public EventQueueThreadClass(EventQueueManager eqm)
34 { 34 {
35 eventQueueManager = eqm; 35 eventQueueManager = eqm;
36 ReadConfig(); 36 ReadConfig();
37 Start(); 37 Start();
38 } 38 }
39 39
40 ~EventQueueThreadClass() 40 ~EventQueueThreadClass()
41 { 41 {
42 Stop(); 42 Stop();
43 } 43 }
44 44
45 45
46 public void ReadConfig() 46 public void ReadConfig()
47 { 47 {
48 ScriptEngineName = eventQueueManager.m_ScriptEngine.ScriptEngineName; 48 ScriptEngineName = eventQueueManager.m_ScriptEngine.ScriptEngineName;
49 nothingToDoSleepms = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50); 49 nothingToDoSleepms = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
50 50
51 // 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
52 string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal"); 52 string pri = eventQueueManager.m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
53 switch (pri.ToLower()) 53 switch (pri.ToLower())
54 { 54 {
55 case "lowest": 55 case "lowest":
56 MyThreadPriority = ThreadPriority.Lowest; 56 MyThreadPriority = ThreadPriority.Lowest;
57 break; 57 break;
58 case "belownormal": 58 case "belownormal":
59 MyThreadPriority = ThreadPriority.BelowNormal; 59 MyThreadPriority = ThreadPriority.BelowNormal;
60 break; 60 break;
61 case "normal": 61 case "normal":
62 MyThreadPriority = ThreadPriority.Normal; 62 MyThreadPriority = ThreadPriority.Normal;
63 break; 63 break;
64 case "abovenormal": 64 case "abovenormal":
65 MyThreadPriority = ThreadPriority.AboveNormal; 65 MyThreadPriority = ThreadPriority.AboveNormal;
66 break; 66 break;
67 case "highest": 67 case "highest":
68 MyThreadPriority = ThreadPriority.Highest; 68 MyThreadPriority = ThreadPriority.Highest;
69 break; 69 break;
70 default: 70 default:
71 MyThreadPriority = ThreadPriority.BelowNormal; // Default 71 MyThreadPriority = ThreadPriority.BelowNormal; // Default
72 eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngineBase", "Unknown priority type \"" + pri + "\" in config file. Defaulting to \"BelowNormal\"."); 72 eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngineBase", "Unknown priority type \"" + pri + "\" in config file. Defaulting to \"BelowNormal\".");
73 break; 73 break;
74 } 74 }
75 75
76 // Now set that priority 76 // Now set that priority
77 if (EventQueueThread != null) 77 if (EventQueueThread != null)
78 if (EventQueueThread.IsAlive) 78 if (EventQueueThread.IsAlive)
79 EventQueueThread.Priority = MyThreadPriority; 79 EventQueueThread.Priority = MyThreadPriority;
80 80
81 } 81 }
82 82
83 83
84 /// <summary> 84 /// <summary>
85 /// Start thread 85 /// Start thread
86 /// </summary> 86 /// </summary>
87 private void Start() 87 private void Start()
88 { 88 {
89 89
90 EventQueueThread = new Thread(EventQueueThreadLoop); 90 EventQueueThread = new Thread(EventQueueThreadLoop);
91 EventQueueThread.IsBackground = true; 91 EventQueueThread.IsBackground = true;
92 92
93 EventQueueThread.Priority = MyThreadPriority; 93 EventQueueThread.Priority = MyThreadPriority;
94 EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; 94 EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
95 EventQueueThread.Start(); 95 EventQueueThread.Start();
96 96
97 // Look at this... Don't you wish everyone did that solid coding everywhere? :P 97 // Look at this... Don't you wish everyone did that solid coding everywhere? :P
98 if (ThreadCount == int.MaxValue) 98 if (ThreadCount == int.MaxValue)
99 ThreadCount = 0; 99 ThreadCount = 0;
100 ThreadCount++; 100 ThreadCount++;
101 } 101 }
102 102
103 public void Stop() 103 public void Stop()
104 { 104 {
105 PleaseShutdown = true; // Set shutdown flag 105 PleaseShutdown = true; // Set shutdown flag
106 Thread.Sleep(100); // Wait a bit 106 Thread.Sleep(100); // Wait a bit
107 if (EventQueueThread != null && EventQueueThread.IsAlive == true) 107 if (EventQueueThread != null && EventQueueThread.IsAlive == true)
108 { 108 {
109 try 109 try
110 { 110 {
111 EventQueueThread.Abort(); // Send abort 111 EventQueueThread.Abort(); // Send abort
112 EventQueueThread.Join(); // Wait for it 112 EventQueueThread.Join(); // Wait for it
113 } 113 }
114 catch (Exception) 114 catch (Exception)
115 { 115 {
116 //myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Exception killing worker thread: " + e.ToString()); 116 //myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Exception killing worker thread: " + e.ToString());
117 } 117 }
118 } 118 }
119 } 119 }
120 120
121 121
122 /// <summary> 122 /// <summary>
123 /// Queue processing thread loop 123 /// Queue processing thread loop
124 /// </summary> 124 /// </summary>
125 private void EventQueueThreadLoop() 125 private void EventQueueThreadLoop()
126 { 126 {
127 //myScriptEngine.m_logger.Verbose(ScriptEngineName, "EventQueueManager Worker thread spawned"); 127 //myScriptEngine.m_logger.Verbose(ScriptEngineName, "EventQueueManager Worker thread spawned");
128 try 128 try
129 { 129 {
130 while (true) 130 while (true)
131 { 131 {
132 try 132 try
133 { 133 {
134 EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct(); 134 EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct();
135 while (true) 135 while (true)
136 { 136 {
137 // Every now and then check if we should shut down 137 // Every now and then check if we should shut down
138 if (PleaseShutdown || eventQueueManager.ThreadsToExit > 0) 138 if (PleaseShutdown || eventQueueManager.ThreadsToExit > 0)
139 { 139 {
140 // Someone should shut down, lets get exclusive lock 140 // Someone should shut down, lets get exclusive lock
141 lock (eventQueueManager.ThreadsToExitLock) 141 lock (eventQueueManager.ThreadsToExitLock)
142 { 142 {
143 // Lets re-check in case someone grabbed it 143 // Lets re-check in case someone grabbed it
144 if (eventQueueManager.ThreadsToExit > 0) 144 if (eventQueueManager.ThreadsToExit > 0)
145 { 145 {
146 // Its crowded here so we'll shut down 146 // Its crowded here so we'll shut down
147 eventQueueManager.ThreadsToExit--; 147 eventQueueManager.ThreadsToExit--;
148 Stop(); 148 Stop();
149 return; 149 return;
150 } 150 }
151 else 151 else
152 { 152 {
153 // We have been asked to shut down 153 // We have been asked to shut down
154 Stop(); 154 Stop();
155 return; 155 return;
156 } 156 }
157 } 157 }
158 } 158 }
159 159
160 160
161 //try 161 //try
162 // { 162 // {
163 EventQueueManager.QueueItemStruct QIS = BlankQIS; 163 EventQueueManager.QueueItemStruct QIS = BlankQIS;
164 bool GotItem = false; 164 bool GotItem = false;
165 165
166 if (PleaseShutdown) 166 if (PleaseShutdown)
167 return; 167 return;
168 168
169 if (eventQueueManager.eventQueue.Count == 0) 169 if (eventQueueManager.eventQueue.Count == 0)
170 { 170 {
171 // Nothing to do? Sleep a bit waiting for something to do 171 // Nothing to do? Sleep a bit waiting for something to do
172 Thread.Sleep(nothingToDoSleepms); 172 Thread.Sleep(nothingToDoSleepms);
173 } 173 }
174 else 174 else
175 { 175 {
176 // Something in queue, process 176 // Something in queue, process
177 //myScriptEngine.m_logger.Verbose(ScriptEngineName, "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);
178 178
179 // 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
180 lock (eventQueueManager.queueLock) 180 lock (eventQueueManager.queueLock)
181 { 181 {
182 GotItem = false; 182 GotItem = false;
183 for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++) 183 for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++)
184 { 184 {
185 // Get queue item 185 // Get queue item
186 QIS = eventQueueManager.eventQueue.Dequeue(); 186 QIS = eventQueueManager.eventQueue.Dequeue();
187 187
188 // Check if object is being processed by someone else 188 // Check if object is being processed by someone else
189 if (eventQueueManager.TryLock(QIS.localID) == false) 189 if (eventQueueManager.TryLock(QIS.localID) == false)
190 { 190 {
191 // Object is already being processed, requeue it 191 // Object is already being processed, requeue it
192 eventQueueManager.eventQueue.Enqueue(QIS); 192 eventQueueManager.eventQueue.Enqueue(QIS);
193 } 193 }
194 else 194 else
195 { 195 {
196 // We have lock on an object and can process it 196 // We have lock on an object and can process it
197 GotItem = true; 197 GotItem = true;
198 break; 198 break;
199 } 199 }
200 } // go through queue 200 } // go through queue
201 } // lock 201 } // lock
202 202
203 if (GotItem == true) 203 if (GotItem == true)
204 { 204 {
205 // Execute function 205 // Execute function
206 try 206 try
207 { 207 {
208#if DEBUG 208#if DEBUG
209 eventQueueManager.m_ScriptEngine.Log.Debug(ScriptEngineName, 209 eventQueueManager.m_ScriptEngine.Log.Debug(ScriptEngineName,
210 "Executing event:\r\n" 210 "Executing event:\r\n"
211 + "QIS.localID: " + QIS.localID 211 + "QIS.localID: " + QIS.localID
212 + ", QIS.itemID: " + QIS.itemID 212 + ", QIS.itemID: " + QIS.itemID
213 + ", QIS.functionName: " + 213 + ", QIS.functionName: " +
214 QIS.functionName); 214 QIS.functionName);
215#endif 215#endif
216 LastExecutionStarted = DateTime.Now.Ticks; 216 LastExecutionStarted = DateTime.Now.Ticks;
217 KillCurrentScript = false; 217 KillCurrentScript = false;
218 InExecution = true; 218 InExecution = true;
219 eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, 219 eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
220 QIS.itemID, 220 QIS.itemID,
221 QIS.functionName, 221 QIS.functionName,
222 QIS.llDetectParams, 222 QIS.llDetectParams,
223 QIS.param); 223 QIS.param);
224 InExecution = false; 224 InExecution = false;
225 } 225 }
226 catch (Exception e) 226 catch (Exception e)
227 { 227 {
228 InExecution = false; 228 InExecution = false;
229 // DISPLAY ERROR INWORLD 229 // DISPLAY ERROR INWORLD
230 string text = "Error executing script function \"" + QIS.functionName + 230 string text = "Error executing script function \"" + QIS.functionName +
231 "\":\r\n"; 231 "\":\r\n";
232 if (e.InnerException != null) 232 if (e.InnerException != null)
233 { 233 {
234 // Send inner exception 234 // Send inner exception
235 text += e.InnerException.Message.ToString(); 235 text += e.InnerException.Message.ToString();
236 } 236 }
237 else 237 else
238 { 238 {
239 text += "\r\n"; 239 text += "\r\n";
240 // Send normal 240 // Send normal
241 text += e.Message.ToString(); 241 text += e.Message.ToString();
242 } 242 }
243 if (KillCurrentScript) 243 if (KillCurrentScript)
244 text += "\r\nScript will be deactivated!"; 244 text += "\r\nScript will be deactivated!";
245 245
246 try 246 try
247 { 247 {
248 if (text.Length > 1500) 248 if (text.Length > 1500)
249 text = text.Substring(0, 1500); 249 text = text.Substring(0, 1500);
250 IScriptHost m_host = 250 IScriptHost m_host =
251 eventQueueManager.m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); 251 eventQueueManager.m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
252 //if (m_host != null) 252 //if (m_host != null)
253 //{ 253 //{
254 eventQueueManager.m_ScriptEngine.World.SimChat(Helpers.StringToField(text), 254 eventQueueManager.m_ScriptEngine.World.SimChat(Helpers.StringToField(text),
255 ChatTypeEnum.Say, 0, 255 ChatTypeEnum.Say, 0,
256 m_host.AbsolutePosition, 256 m_host.AbsolutePosition,
257 m_host.Name, m_host.UUID); 257 m_host.Name, m_host.UUID);
258 } 258 }
259 catch 259 catch
260 { 260 {
261 //} 261 //}
262 //else 262 //else
263 //{ 263 //{
264 // T oconsole 264 // T oconsole
265 eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName, 265 eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName,
266 "Unable to send text in-world:\r\n" + 266 "Unable to send text in-world:\r\n" +
267 text); 267 text);
268 } 268 }
269 finally 269 finally
270 { 270 {
271 // So we are done sending message in-world 271 // So we are done sending message in-world
272 if (KillCurrentScript) 272 if (KillCurrentScript)
273 { 273 {
274 eventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript( 274 eventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
275 QIS.localID, QIS.itemID); 275 QIS.localID, QIS.itemID);
276 } 276 }
277 } 277 }
278 } 278 }
279 finally 279 finally
280 { 280 {
281 InExecution = false; 281 InExecution = false;
282 eventQueueManager.ReleaseLock(QIS.localID); 282 eventQueueManager.ReleaseLock(QIS.localID);
283 } 283 }
284 } 284 }
285 } // Something in queue 285 } // Something in queue
286 } 286 }
287 } 287 }
288 catch (ThreadAbortException tae) 288 catch (ThreadAbortException tae)
289 { 289 {
290 eventQueueManager.m_ScriptEngine.Log.Notice(ScriptEngineName, "ThreadAbortException while executing function."); 290 eventQueueManager.m_ScriptEngine.Log.Notice(ScriptEngineName, "ThreadAbortException while executing function.");
291 } 291 }
292 catch (Exception e) 292 catch (Exception e)
293 { 293 {
294 eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName, "Exception in EventQueueThreadLoop: " + e.ToString()); 294 eventQueueManager.m_ScriptEngine.Log.Error(ScriptEngineName, "Exception in EventQueueThreadLoop: " + e.ToString());
295 } 295 }
296 } // while 296 } // while
297 } // try 297 } // try
298 catch (ThreadAbortException) 298 catch (ThreadAbortException)
299 { 299 {
300 //myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Worker thread killed: " + tae.Message); 300 //myScriptEngine.Log.Verbose(ScriptEngineName, "EventQueueManager Worker thread killed: " + tae.Message);
301 } 301 }
302 } 302 }
303 303
304 /// <summary> 304 /// <summary>
305 /// If set to true then threads and stuff should try to make a graceful exit 305 /// If set to true then threads and stuff should try to make a graceful exit
306 /// </summary> 306 /// </summary>
307 public bool PleaseShutdown 307 public bool PleaseShutdown
308 { 308 {
309 get { return _PleaseShutdown; } 309 get { return _PleaseShutdown; }
310 set { _PleaseShutdown = value; } 310 set { _PleaseShutdown = value; }
311 } 311 }
312 private bool _PleaseShutdown = false; 312 private bool _PleaseShutdown = false;
313 } 313 }
314} 314}
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
index fc2fda9..ae6f001 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
@@ -1,163 +1,163 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using System.Threading; 4using System.Threading;
5 5
6namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 6namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
7{ 7{
8 /// <summary> 8 /// <summary>
9 /// This class does maintenance on script engine. 9 /// This class does maintenance on script engine.
10 /// </summary> 10 /// </summary>
11 public class MaintenanceThread : iScriptEngineFunctionModule 11 public class MaintenanceThread : iScriptEngineFunctionModule
12 { 12 {
13 public ScriptEngine m_ScriptEngine; 13 public ScriptEngine m_ScriptEngine;
14 private int MaintenanceLoopms; 14 private int MaintenanceLoopms;
15 15
16 public MaintenanceThread(ScriptEngine _ScriptEngine) 16 public MaintenanceThread(ScriptEngine _ScriptEngine)
17 { 17 {
18 m_ScriptEngine = _ScriptEngine; 18 m_ScriptEngine = _ScriptEngine;
19 19
20 ReadConfig(); 20 ReadConfig();
21 21
22 // Start maintenance thread 22 // Start maintenance thread
23 StartMaintenanceThread(); 23 StartMaintenanceThread();
24 } 24 }
25 25
26 ~MaintenanceThread() 26 ~MaintenanceThread()
27 { 27 {
28 StopMaintenanceThread(); 28 StopMaintenanceThread();
29 } 29 }
30 30
31 public void ReadConfig() 31 public void ReadConfig()
32 { 32 {
33 MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50); 33 MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50);
34 } 34 }
35 35
36 36
37 #region " Maintenance thread " 37 #region " Maintenance thread "
38 /// <summary> 38 /// <summary>
39 /// Maintenance thread. Enforcing max execution time for example. 39 /// Maintenance thread. Enforcing max execution time for example.
40 /// </summary> 40 /// </summary>
41 public Thread MaintenanceThreadThread; 41 public Thread MaintenanceThreadThread;
42 42
43 /// <summary> 43 /// <summary>
44 /// Starts maintenance thread 44 /// Starts maintenance thread
45 /// </summary> 45 /// </summary>
46 private void StartMaintenanceThread() 46 private void StartMaintenanceThread()
47 { 47 {
48 if (MaintenanceThreadThread == null) 48 if (MaintenanceThreadThread == null)
49 { 49 {
50 MaintenanceThreadThread = new Thread(MaintenanceLoop); 50 MaintenanceThreadThread = new Thread(MaintenanceLoop);
51 MaintenanceThreadThread.Name = "ScriptMaintenanceThread"; 51 MaintenanceThreadThread.Name = "ScriptMaintenanceThread";
52 MaintenanceThreadThread.IsBackground = true; 52 MaintenanceThreadThread.IsBackground = true;
53 MaintenanceThreadThread.Start(); 53 MaintenanceThreadThread.Start();
54 } 54 }
55 } 55 }
56 56
57 /// <summary> 57 /// <summary>
58 /// Stops maintenance thread 58 /// Stops maintenance thread
59 /// </summary> 59 /// </summary>
60 private void StopMaintenanceThread() 60 private void StopMaintenanceThread()
61 { 61 {
62#if DEBUG 62#if DEBUG
63 m_ScriptEngine.Log.Debug(m_ScriptEngine.ScriptEngineName, "StopMaintenanceThread() called"); 63 m_ScriptEngine.Log.Debug(m_ScriptEngine.ScriptEngineName, "StopMaintenanceThread() called");
64#endif 64#endif
65 PleaseShutdown = true; 65 PleaseShutdown = true;
66 Thread.Sleep(100); 66 Thread.Sleep(100);
67 try 67 try
68 { 68 {
69 if (MaintenanceThreadThread != null) 69 if (MaintenanceThreadThread != null)
70 { 70 {
71 if (MaintenanceThreadThread.IsAlive) 71 if (MaintenanceThreadThread.IsAlive)
72 { 72 {
73 MaintenanceThreadThread.Abort(); 73 MaintenanceThreadThread.Abort();
74 } 74 }
75 } 75 }
76 } 76 }
77 catch (Exception ex) 77 catch (Exception ex)
78 { 78 {
79 m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception stopping maintenence thread: " + ex.ToString()); 79 m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception stopping maintenence thread: " + ex.ToString());
80 } 80 }
81 81
82 } 82 }
83 83
84 /// <summary> 84 /// <summary>
85 /// A thread should run in this loop and check all running scripts 85 /// A thread should run in this loop and check all running scripts
86 /// </summary> 86 /// </summary>
87 public void MaintenanceLoop() 87 public void MaintenanceLoop()
88 { 88 {
89 if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms) 89 if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms)
90 m_ScriptEngine.Log.Warn(m_ScriptEngine.ScriptEngineName, 90 m_ScriptEngine.Log.Warn(m_ScriptEngine.ScriptEngineName,
91 "Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run."); 91 "Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run.");
92 92
93 while (true) 93 while (true)
94 { 94 {
95 try 95 try
96 { 96 {
97 long Last_maxFunctionExecutionTimens = 0; // DateTime.Now.Ticks; 97 long Last_maxFunctionExecutionTimens = 0; // DateTime.Now.Ticks;
98 long Last_ReReadConfigFilens = DateTime.Now.Ticks; 98 long Last_ReReadConfigFilens = DateTime.Now.Ticks;
99 while (true) 99 while (true)
100 { 100 {
101 System.Threading.Thread.Sleep(MaintenanceLoopms); // Sleep before next pass 101 System.Threading.Thread.Sleep(MaintenanceLoopms); // Sleep before next pass
102 if (PleaseShutdown) 102 if (PleaseShutdown)
103 return; 103 return;
104 104
105 if (m_ScriptEngine != null) 105 if (m_ScriptEngine != null)
106 { 106 {
107 // 107 //
108 // Re-reading config every x seconds 108 // Re-reading config every x seconds
109 // 109 //
110 if (m_ScriptEngine.RefreshConfigFileSeconds > 0) 110 if (m_ScriptEngine.RefreshConfigFileSeconds > 0)
111 { 111 {
112 // Check if its time to re-read config 112 // Check if its time to re-read config
113 if (DateTime.Now.Ticks - Last_ReReadConfigFilens > m_ScriptEngine.RefreshConfigFilens) 113 if (DateTime.Now.Ticks - Last_ReReadConfigFilens > m_ScriptEngine.RefreshConfigFilens)
114 { 114 {
115 // Its time to re-read config file 115 // Its time to re-read config file
116 m_ScriptEngine.ReadConfig(); 116 m_ScriptEngine.ReadConfig();
117 Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time 117 Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time
118 } 118 }
119 } 119 }
120 120
121 // 121 //
122 // Adjust number of running script threads if not correct 122 // Adjust number of running script threads if not correct
123 // 123 //
124 if (m_ScriptEngine.m_EventQueueManager != null) 124 if (m_ScriptEngine.m_EventQueueManager != null)
125 m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads(); 125 m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads();
126 126
127 // 127 //
128 // Check if any script has exceeded its max execution time 128 // Check if any script has exceeded its max execution time
129 // 129 //
130 if (m_ScriptEngine.m_EventQueueManager != null && m_ScriptEngine.m_EventQueueManager.EnforceMaxExecutionTime) 130 if (m_ScriptEngine.m_EventQueueManager != null && m_ScriptEngine.m_EventQueueManager.EnforceMaxExecutionTime)
131 { 131 {
132 // We are enforcing execution time 132 // We are enforcing execution time
133 if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens > 133 if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens >
134 m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens) 134 m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens)
135 { 135 {
136 // Its time to check again 136 // Its time to check again
137 m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check 137 m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check
138 Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time 138 Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time
139 } 139 }
140 } 140 }
141 } // m_ScriptEngine != null 141 } // m_ScriptEngine != null
142 } 142 }
143 } 143 }
144 catch (Exception ex) 144 catch (Exception ex)
145 { 145 {
146 m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString()); 146 m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString());
147 Thread.Sleep(5000); 147 Thread.Sleep(5000);
148 } 148 }
149 } 149 }
150 } 150 }
151 #endregion 151 #endregion
152 /// <summary> 152 /// <summary>
153 /// If set to true then threads and stuff should try to make a graceful exit 153 /// If set to true then threads and stuff should try to make a graceful exit
154 /// </summary> 154 /// </summary>
155 public bool PleaseShutdown 155 public bool PleaseShutdown
156 { 156 {
157 get { return _PleaseShutdown; } 157 get { return _PleaseShutdown; }
158 set { _PleaseShutdown = value; } 158 set { _PleaseShutdown = value; }
159 } 159 }
160 private bool _PleaseShutdown = false; 160 private bool _PleaseShutdown = false;
161 161
162 } 162 }
163} 163}
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs
index 7539074..ded85b3 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/iScriptEngineFunctionModule.cs
@@ -1,12 +1,12 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4 4
5namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 5namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
6{ 6{
7 public interface iScriptEngineFunctionModule 7 public interface iScriptEngineFunctionModule
8 { 8 {
9 void ReadConfig(); 9 void ReadConfig();
10 bool PleaseShutdown { get; set; } 10 bool PleaseShutdown { get; set; }
11 } 11 }
12} \ No newline at end of file 12} \ No newline at end of file