aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
diff options
context:
space:
mode:
authorTedd Hansen2008-02-01 22:18:55 +0000
committerTedd Hansen2008-02-01 22:18:55 +0000
commita6726b0c9de4ef875348f9dcbf21a9c93bde8a09 (patch)
treebcf0fbbe7306172e2933f59799813f84ed5a621f /OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
parentThank you, Kinoc for the ChatModule.cs updates. (diff)
downloadopensim-SC_OLD-a6726b0c9de4ef875348f9dcbf21a9c93bde8a09.zip
opensim-SC_OLD-a6726b0c9de4ef875348f9dcbf21a9c93bde8a09.tar.gz
opensim-SC_OLD-a6726b0c9de4ef875348f9dcbf21a9c93bde8a09.tar.bz2
opensim-SC_OLD-a6726b0c9de4ef875348f9dcbf21a9c93bde8a09.tar.xz
SCRIPT SUPPORT IS STILL BROKEN.
Bugfix: Scripts exceeding max and set to be killed were not killed, only removed. Added ability to re-read configuration while OpenSim is running All regions now sharing one MaintenanceThread New MaintenanceThread: - checks for script execution timeout - re-reads config - starts/stops threads if thread active count becomes too high/low compared to config Speed increase on event execution: - Reuse of try{}catch{} blocks - Time calculation on event execution
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs220
1 files changed, 127 insertions, 93 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
index 57caad5..e610c36 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs
@@ -19,7 +19,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
19 /// </summary> 19 /// </summary>
20 private int nothingToDoSleepms;// = 50; 20 private int nothingToDoSleepms;// = 50;
21 21
22 public DateTime LastExecutionStarted; 22 public long LastExecutionStarted;
23 public bool InExecution = false; 23 public bool InExecution = false;
24 public bool KillCurrentScript = false; 24 public bool KillCurrentScript = false;
25 25
@@ -109,120 +109,154 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
109 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned"); 109 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned");
110 try 110 try
111 { 111 {
112 EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct(); 112 while (true)
113 while (true)
114 { 113 {
115 try 114 try
116 { 115 {
117 EventQueueManager.QueueItemStruct QIS = BlankQIS; 116 EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct();
118 bool GotItem = false; 117 while (true)
119
120 if (eventQueueManager.eventQueue.Count == 0)
121 {
122 // Nothing to do? Sleep a bit waiting for something to do
123 Thread.Sleep(nothingToDoSleepms);
124 }
125 else
126 { 118 {
127 // Something in queue, process 119 // Every now and then check if we should shut down
128 //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); 120 if (eventQueueManager.ThreadsToExit > 0)
129
130 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
131 lock (eventQueueManager.queueLock)
132 { 121 {
133 GotItem = false; 122 // Someone should shut down, lets get exclusive lock
134 for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++) 123 lock (eventQueueManager.ThreadsToExitLock)
135 { 124 {
136 // Get queue item 125 // Lets re-check in case someone grabbed it
137 QIS = eventQueueManager.eventQueue.Dequeue(); 126 if (eventQueueManager.ThreadsToExit > 0)
138
139 // Check if object is being processed by someone else
140 if (eventQueueManager.TryLock(QIS.localID) == false)
141 {
142 // Object is already being processed, requeue it
143 eventQueueManager.eventQueue.Enqueue(QIS);
144 }
145 else
146 { 127 {
147 // We have lock on an object and can process it 128 // We are go for shutdown
148 GotItem = true; 129 eventQueueManager.ThreadsToExit--;
149 break; 130 Shutdown();
131 return;
150 } 132 }
151 } // go through queue 133 }
152 } // lock 134 }
153 135
154 if (GotItem == true) 136
137 //try
138 // {
139 EventQueueManager.QueueItemStruct QIS = BlankQIS;
140 bool GotItem = false;
141
142 if (eventQueueManager.eventQueue.Count == 0)
155 { 143 {
156 // Execute function 144 // Nothing to do? Sleep a bit waiting for something to do
157 try 145 Thread.Sleep(nothingToDoSleepms);
158 { 146 }
159#if DEBUG 147 else
160 eventQueueManager.m_ScriptEngine.Log.Debug("ScriptEngine", "Executing event:\r\n" 148 {
161 + "QIS.localID: " + QIS.localID 149 // Something in queue, process
162 + ", QIS.itemID: " + QIS.itemID 150 //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
163 + ", QIS.functionName: " + QIS.functionName); 151
164#endif 152 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
165 LastExecutionStarted = DateTime.Now; 153 lock (eventQueueManager.queueLock)
166 KillCurrentScript = false;
167 InExecution = true;
168 eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID,
169 QIS.functionName, QIS.llDetectParams, QIS.param);
170 InExecution = false;
171 }
172 catch (Exception e)
173 { 154 {
174 InExecution = false; 155 GotItem = false;
175 // DISPLAY ERROR INWORLD 156 for (int qc = 0; qc < eventQueueManager.eventQueue.Count; qc++)
176 string text = "Error executing script function \"" + QIS.functionName + "\":\r\n";
177 if (e.InnerException != null)
178 { 157 {
179 // Send inner exception 158 // Get queue item
180 text += e.InnerException.Message.ToString(); 159 QIS = eventQueueManager.eventQueue.Dequeue();
181 } 160
182 else 161 // Check if object is being processed by someone else
183 { 162 if (eventQueueManager.TryLock(QIS.localID) == false)
184 text += "\r\n"; 163 {
185 // Send normal 164 // Object is already being processed, requeue it
186 text += e.Message.ToString(); 165 eventQueueManager.eventQueue.Enqueue(QIS);
187 } 166 }
188 if (KillCurrentScript) 167 else
189 text += "\r\nScript will be deactivated!"; 168 {
169 // We have lock on an object and can process it
170 GotItem = true;
171 break;
172 }
173 } // go through queue
174 } // lock
190 175
176 if (GotItem == true)
177 {
178 // Execute function
191 try 179 try
192 { 180 {
193 if (text.Length > 1500) 181#if DEBUG
194 text = text.Substring(0, 1500); 182 eventQueueManager.m_ScriptEngine.Log.Debug("ScriptEngine",
195 IScriptHost m_host = eventQueueManager.m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); 183 "Executing event:\r\n"
196 //if (m_host != null) 184 + "QIS.localID: " + QIS.localID
197 //{ 185 + ", QIS.itemID: " + QIS.itemID
198 eventQueueManager.m_ScriptEngine.World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, 186 + ", QIS.functionName: " +
199 m_host.AbsolutePosition, m_host.Name, m_host.UUID); 187 QIS.functionName);
200 } 188#endif
201 catch 189 LastExecutionStarted = DateTime.Now.Ticks;
202 { 190 KillCurrentScript = false;
203 //} 191 InExecution = true;
204 //else 192 eventQueueManager.m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
205 //{ 193 QIS.itemID,
206 // T oconsole 194 QIS.functionName,
207 eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine", 195 QIS.llDetectParams,
208 "Unable to send text in-world:\r\n" + text); 196 QIS.param);
197 InExecution = false;
209 } 198 }
210 finally 199 catch (Exception e)
211 { 200 {
212 // So we are done sending message in-world 201 InExecution = false;
202 // DISPLAY ERROR INWORLD
203 string text = "Error executing script function \"" + QIS.functionName +
204 "\":\r\n";
205 if (e.InnerException != null)
206 {
207 // Send inner exception
208 text += e.InnerException.Message.ToString();
209 }
210 else
211 {
212 text += "\r\n";
213 // Send normal
214 text += e.Message.ToString();
215 }
213 if (KillCurrentScript) 216 if (KillCurrentScript)
217 text += "\r\nScript will be deactivated!";
218
219 try
220 {
221 if (text.Length > 1500)
222 text = text.Substring(0, 1500);
223 IScriptHost m_host =
224 eventQueueManager.m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
225 //if (m_host != null)
226 //{
227 eventQueueManager.m_ScriptEngine.World.SimChat(Helpers.StringToField(text),
228 ChatTypeEnum.Say, 0,
229 m_host.AbsolutePosition,
230 m_host.Name, m_host.UUID);
231 }
232 catch
214 { 233 {
215 eventQueueManager.m_ScriptEngine.m_ScriptManager.RemoveScript(QIS.localID, QIS.itemID); 234 //}
235 //else
236 //{
237 // T oconsole
238 eventQueueManager.m_ScriptEngine.Log.Error("ScriptEngine",
239 "Unable to send text in-world:\r\n" +
240 text);
241 }
242 finally
243 {
244 // So we are done sending message in-world
245 if (KillCurrentScript)
246 {
247 eventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
248 QIS.localID, QIS.itemID);
249 }
216 } 250 }
217 } 251 }
252 finally
253 {
254 InExecution = false;
255 eventQueueManager.ReleaseLock(QIS.localID);
256 }
218 } 257 }
219 finally 258 } // Something in queue
220 { 259 }
221 InExecution = false;
222 eventQueueManager.ReleaseLock(QIS.localID);
223 }
224 }
225 } // Something in queue
226 } 260 }
227 catch (ThreadAbortException tae) 261 catch (ThreadAbortException tae)
228 { 262 {