aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/AsyncCommandManager.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/AsyncCommandManager.cs270
1 files changed, 270 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandManager.cs
new file mode 100644
index 0000000..4ec7916
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/XEngine/AsyncCommandManager.cs
@@ -0,0 +1,270 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Threading;
32using libsecondlife;
33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins;
36using Timer=OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins.Timer;
37using Dataserver=OpenSim.Region.ScriptEngine.XEngine.AsyncCommandPlugins.Dataserver;
38
39namespace OpenSim.Region.ScriptEngine.XEngine
40{
41 /// <summary>
42 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
43 /// </summary>
44 public class AsyncCommandManager
45 {
46 private static Thread cmdHandlerThread;
47 private static int cmdHandlerThreadCycleSleepms;
48
49 public XEngine m_ScriptEngine;
50
51 public Dataserver m_Dataserver;
52 public Timer m_Timer;
53 public HttpRequest m_HttpRequest;
54 public Listener m_Listener;
55 public SensorRepeat m_SensorRepeat;
56 public XmlRequest m_XmlRequest;
57
58 public AsyncCommandManager(XEngine _ScriptEngine)
59 {
60 m_ScriptEngine = _ScriptEngine;
61 ReadConfig();
62
63 // Create instances of all plugins
64 m_Dataserver = new Dataserver(this);
65 m_Timer = new Timer(this);
66 m_HttpRequest = new HttpRequest(this);
67 m_Listener = new Listener(this);
68 m_SensorRepeat = new SensorRepeat(this);
69 m_XmlRequest = new XmlRequest(this);
70
71 StartThread();
72 }
73
74 private static void StartThread()
75 {
76 if (cmdHandlerThread == null)
77 {
78 // Start the thread that will be doing the work
79 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
80 cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread";
81 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
82 cmdHandlerThread.IsBackground = true;
83 cmdHandlerThread.Start();
84 ThreadTracker.Add(cmdHandlerThread);
85 }
86 }
87
88 public void ReadConfig()
89 {
90 cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 100);
91 }
92
93 ~AsyncCommandManager()
94 {
95 // Shut down thread
96 try
97 {
98 if (cmdHandlerThread != null)
99 {
100 if (cmdHandlerThread.IsAlive == true)
101 {
102 cmdHandlerThread.Abort();
103 //cmdHandlerThread.Join();
104 }
105 }
106 }
107 catch
108 {
109 }
110 }
111
112 private static void CmdHandlerThreadLoop()
113 {
114 while (true)
115 {
116 try
117 {
118 while (true)
119 {
120 Thread.Sleep(cmdHandlerThreadCycleSleepms);
121
122 foreach (XEngine xe in XEngine.ScriptEngines)
123 {
124 xe.m_ASYNCLSLCommandManager.DoOneCmdHandlerPass();
125 }
126 }
127 }
128 catch
129 {
130 }
131 }
132 }
133
134 internal void DoOneCmdHandlerPass()
135 {
136 // Check timers
137 m_Timer.CheckTimerEvents();
138 // Check HttpRequests
139 m_HttpRequest.CheckHttpRequests();
140 // Check XMLRPCRequests
141 m_XmlRequest.CheckXMLRPCRequests();
142 // Check Listeners
143 m_Listener.CheckListeners();
144 // Check Sensors
145 m_SensorRepeat.CheckSenseRepeaterEvents();
146 // Check dataserver
147 m_Dataserver.ExpireRequests();
148 }
149
150 /// <summary>
151 /// Remove a specific script (and all its pending commands)
152 /// </summary>
153 /// <param name="localID"></param>
154 /// <param name="itemID"></param>
155 public void RemoveScript(uint localID, LLUUID itemID)
156 {
157 // Remove a specific script
158
159 // Remove dataserver events
160 m_Dataserver.RemoveEvents(localID, itemID);
161
162 // Remove from: Timers
163 m_Timer.UnSetTimerEvents(localID, itemID);
164
165 // Remove from: HttpRequest
166 IHttpRequests iHttpReq =
167 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
168 iHttpReq.StopHttpRequest(localID, itemID);
169
170 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
171 comms.DeleteListener(itemID);
172
173 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
174 xmlrpc.DeleteChannels(itemID);
175 xmlrpc.CancelSRDRequests(itemID);
176
177 // Remove Sensors
178 m_SensorRepeat.UnSetSenseRepeaterEvents(localID, itemID);
179
180 }
181
182 public Object[] GetSerializationData(LLUUID itemID)
183 {
184 List<Object> data = new List<Object>();
185
186 Object[] listeners=m_Listener.GetSerializationData(itemID);
187 if(listeners.Length > 0)
188 {
189 data.Add("listener");
190 data.Add(listeners.Length);
191 data.AddRange(listeners);
192 }
193
194 Object[] timers=m_Timer.GetSerializationData(itemID);
195 if(timers.Length > 0)
196 {
197 data.Add("timer");
198 data.Add(timers.Length);
199 data.AddRange(timers);
200 }
201
202 Object[] sensors=m_SensorRepeat.GetSerializationData(itemID);
203 if(sensors.Length > 0)
204 {
205 data.Add("sensor");
206 data.Add(sensors.Length);
207 data.AddRange(sensors);
208 }
209
210 return data.ToArray();
211 }
212
213 public void CreateFromData(uint localID, LLUUID itemID, LLUUID hostID,
214 Object[] data)
215 {
216 int idx=0;
217 int len;
218
219 while(idx < data.Length)
220 {
221 string type = data[idx].ToString();
222 len = (int)data[idx+1];
223 idx+=2;
224
225 if(len > 0)
226 {
227 Object[] item = new Object[len];
228 Array.Copy(data, idx, item, 0, len);
229
230 idx+=len;
231
232 switch(type)
233 {
234 case "listener":
235 m_Listener.CreateFromData(localID, itemID, hostID,
236 item);
237 break;
238 case "timer":
239 m_Timer.CreateFromData(localID, itemID, hostID, item);
240 break;
241 case "sensor":
242 m_SensorRepeat.CreateFromData(localID, itemID, hostID,
243 item);
244 break;
245 }
246 }
247 }
248 }
249
250 #region Check llRemoteData channels
251
252
253 #endregion
254
255 #region Check llListeners
256
257
258 #endregion
259
260 /// <summary>
261 /// If set to true then threads and stuff should try to make a graceful exit
262 /// </summary>
263 public bool PleaseShutdown
264 {
265 get { return _PleaseShutdown; }
266 set { _PleaseShutdown = value; }
267 }
268 private bool _PleaseShutdown = false;
269 }
270}