aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs410
1 files changed, 262 insertions, 148 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
index af8a62e..a45de1e 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/LSLLongCmdHandler.cs
@@ -1,148 +1,262 @@
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;
6 6using OpenSim.Region.ScriptEngine.Common;
7namespace OpenSim.Region.ScriptEngine.DotNetEngine 7
8{ 8namespace OpenSim.Region.ScriptEngine.DotNetEngine
9 /// <summary> 9{
10 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. 10 /// <summary>
11 /// </summary> 11 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
12 class LSLLongCmdHandler 12 /// </summary>
13 { 13 class LSLLongCmdHandler
14 private Thread cmdHandlerThread; 14 {
15 private int cmdHandlerThreadCycleSleepms = 100; 15 private Thread cmdHandlerThread;
16 16 private int cmdHandlerThreadCycleSleepms = 100;
17 private ScriptEngine m_ScriptEngine; 17
18 public LSLLongCmdHandler(ScriptEngine _ScriptEngine) 18 private ScriptEngine m_ScriptEngine;
19 { 19 public LSLLongCmdHandler(ScriptEngine _ScriptEngine)
20 m_ScriptEngine = _ScriptEngine; 20 {
21 21 m_ScriptEngine = _ScriptEngine;
22 // Start the thread that will be doing the work 22
23 cmdHandlerThread = new Thread(CmdHandlerThreadLoop); 23 // Start the thread that will be doing the work
24 cmdHandlerThread.Name = "CmdHandlerThread"; 24 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
25 cmdHandlerThread.Priority = ThreadPriority.BelowNormal; 25 cmdHandlerThread.Name = "CmdHandlerThread";
26 cmdHandlerThread.IsBackground = true; 26 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
27 cmdHandlerThread.Start(); 27 cmdHandlerThread.IsBackground = true;
28 } 28 cmdHandlerThread.Start();
29 ~LSLLongCmdHandler() 29 }
30 { 30 ~LSLLongCmdHandler()
31 // Shut down thread 31 {
32 try 32 // Shut down thread
33 { 33 try
34 if (cmdHandlerThread != null) 34 {
35 { 35 if (cmdHandlerThread != null)
36 if (cmdHandlerThread.IsAlive == true) 36 {
37 { 37 if (cmdHandlerThread.IsAlive == true)
38 cmdHandlerThread.Abort(); 38 {
39 cmdHandlerThread.Join(); 39 cmdHandlerThread.Abort();
40 } 40 cmdHandlerThread.Join();
41 } 41 }
42 } 42 }
43 catch { } 43 }
44 } 44 catch { }
45 45 }
46 private void CmdHandlerThreadLoop() 46
47 { 47 private void CmdHandlerThreadLoop()
48 while (true) 48 {
49 { 49 while (true)
50 // Check timers 50 {
51 CheckTimerEvents(); 51 // Check timers
52 52 CheckTimerEvents();
53 // Sleep before next cycle 53 // Check HttpRequests
54 Thread.Sleep(cmdHandlerThreadCycleSleepms); 54 CheckHttpRequests();
55 } 55
56 } 56 // Sleep before next cycle
57 57 Thread.Sleep(cmdHandlerThreadCycleSleepms);
58 /// <summary> 58 }
59 /// Remove a specific script (and all its pending commands) 59 }
60 /// </summary> 60
61 /// <param name="m_localID"></param> 61 /// <summary>
62 /// <param name="m_itemID"></param> 62 /// Remove a specific script (and all its pending commands)
63 public void RemoveScript(uint m_localID, LLUUID m_itemID) 63 /// </summary>
64 { 64 /// <param name="m_localID"></param>
65 // Remove a specific script 65 /// <param name="m_itemID"></param>
66 66 public void RemoveScript(uint localID, LLUUID itemID)
67 // Remove from: Timers 67 {
68 UnSetTimerEvents(m_localID, m_itemID); 68 // Remove a specific script
69 } 69
70 70 // Remove from: Timers
71 71 UnSetTimerEvents(localID, itemID);
72 // 72 // Remove from: HttpRequest
73 // TIMER 73 StopHttpRequest(localID, itemID);
74 // 74 }
75 private class TimerClass 75
76 { 76 #region TIMER
77 public uint localID; 77
78 public LLUUID itemID; 78 //
79 public double interval; 79 // TIMER
80 public DateTime next; 80 //
81 } 81 private class TimerClass
82 private List<TimerClass> Timers = new List<TimerClass>(); 82 {
83 private object ListLock = new object(); 83 public uint localID;
84 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) 84 public LLUUID itemID;
85 { 85 public double interval;
86 Console.WriteLine("SetTimerEvent"); 86 public DateTime next;
87 87 }
88 // Always remove first, in case this is a re-set 88 private List<TimerClass> Timers = new List<TimerClass>();
89 UnSetTimerEvents(m_localID, m_itemID); 89 private object TimerListLock = new object();
90 if (sec == 0) // Disabling timer 90 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
91 return; 91 {
92 92 Console.WriteLine("SetTimerEvent");
93 // Add to timer 93
94 TimerClass ts = new TimerClass(); 94 // Always remove first, in case this is a re-set
95 ts.localID = m_localID; 95 UnSetTimerEvents(m_localID, m_itemID);
96 ts.itemID = m_itemID; 96 if (sec == 0) // Disabling timer
97 ts.interval = sec; 97 return;
98 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 98
99 lock (ListLock) 99 // Add to timer
100 { 100 TimerClass ts = new TimerClass();
101 Timers.Add(ts); 101 ts.localID = m_localID;
102 } 102 ts.itemID = m_itemID;
103 } 103 ts.interval = sec;
104 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) 104 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
105 { 105 lock (TimerListLock)
106 // Remove from timer 106 {
107 lock (ListLock) 107 Timers.Add(ts);
108 { 108 }
109 List<TimerClass> NewTimers = new List<TimerClass>(); 109 }
110 foreach (TimerClass ts in Timers) 110 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
111 { 111 {
112 if (ts.localID != m_localID && ts.itemID != m_itemID) 112 // Remove from timer
113 { 113 lock (TimerListLock)
114 NewTimers.Add(ts); 114 {
115 } 115 List<TimerClass> NewTimers = new List<TimerClass>();
116 } 116 foreach (TimerClass ts in Timers)
117 Timers.Clear(); 117 {
118 Timers = NewTimers; 118 if (ts.localID != m_localID && ts.itemID != m_itemID)
119 } 119 {
120 } 120 NewTimers.Add(ts);
121 public void CheckTimerEvents() 121 }
122 { 122 }
123 // Nothing to do here? 123 Timers.Clear();
124 if (Timers.Count == 0) 124 Timers = NewTimers;
125 return; 125 }
126 126 }
127 lock (ListLock) 127 public void CheckTimerEvents()
128 { 128 {
129 129 // Nothing to do here?
130 // Go through all timers 130 if (Timers.Count == 0)
131 foreach (TimerClass ts in Timers) 131 return;
132 { 132
133 // Time has passed? 133 lock (TimerListLock)
134 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) 134 {
135 { 135
136 // Add it to queue 136 // Go through all timers
137 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", new object[] { }); 137 foreach (TimerClass ts in Timers)
138 // set next interval 138 {
139 139 // Time has passed?
140 140 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
141 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 141 {
142 } 142 // Add it to queue
143 } 143 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", new object[] { });
144 } // lock 144 // set next interval
145 } 145
146 146
147 } 147 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
148} 148 }
149 }
150 } // lock
151 }
152 #endregion
153
154 #region HTTP REQUEST
155
156 //
157 // HTTP REAQUEST
158 //
159 private class HttpClass
160 {
161 public uint localID;
162 public LLUUID itemID;
163 public string url;
164 public List<string> parameters;
165 public string body;
166 public DateTime next;
167
168 public string response_request_id;
169 public int response_status;
170 public List<string> response_metadata;
171 public string response_body;
172
173 public void SendRequest()
174 {
175 // TODO: SEND REQUEST!!!
176 }
177 public void Stop()
178 {
179 // TODO: Cancel any ongoing request
180 }
181 public bool CheckResponse()
182 {
183 // TODO: Check if we got a response yet, return true if so -- false if not
184 return true;
185
186 // TODO: If we got a response, set the following then return true
187 //response_request_id
188 //response_status
189 //response_metadata
190 //response_body
191
192 }
193 }
194 private List<HttpClass> HttpRequests = new List<HttpClass>();
195 private object HttpListLock = new object();
196 public void StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body)
197 {
198 Console.WriteLine("StartHttpRequest");
199
200 HttpClass htc = new HttpClass();
201 htc.localID = localID;
202 htc.itemID = itemID;
203 htc.url = url;
204 htc.parameters = parameters;
205 htc.body = body;
206 lock (HttpListLock)
207 {
208
209 //ADD REQUEST
210 HttpRequests.Add(htc);
211 }
212 }
213 public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
214 {
215 // Remove from list
216 lock (HttpListLock)
217 {
218 List<HttpClass> NewHttpList = new List<HttpClass>();
219 foreach (HttpClass ts in HttpRequests)
220 {
221 if (ts.localID != m_localID && ts.itemID != m_itemID)
222 {
223 // Keeping this one
224 NewHttpList.Add(ts);
225 }
226 else
227 {
228 // Shutting this one down
229 ts.Stop();
230 }
231 }
232 HttpRequests.Clear();
233 HttpRequests = NewHttpList;
234 }
235 }
236 public void CheckHttpRequests()
237 {
238 // Nothing to do here?
239 if (HttpRequests.Count == 0)
240 return;
241
242 lock (HttpListLock)
243 {
244 foreach (HttpClass ts in HttpRequests)
245 {
246
247 if (ts.CheckResponse() == true)
248 {
249 // Add it to event queue
250 //key request_id, integer status, list metadata, string body
251 object[] resobj = new object[] { ts.response_request_id, ts.response_status, ts.response_metadata, ts.response_body };
252 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "http_response", resobj);
253 // Now stop it
254 StopHttpRequest(ts.localID, ts.itemID);
255 }
256 }
257 } // lock
258 }
259 #endregion
260
261 }
262}