diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs | 624 |
1 files changed, 312 insertions, 312 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 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Threading; | 31 | using System.Threading; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Interfaces; |
34 | using OpenSim.Region.Environment.Modules; | 34 | using OpenSim.Region.Environment.Modules; |
35 | 35 | ||
36 | namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase | 36 | namespace 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 |