aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/HttpServer
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs36
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs15
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs290
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs16
4 files changed, 340 insertions, 17 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index f57ea76..e45cb89 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -1448,10 +1448,34 @@ namespace OpenSim.Framework.Servers.HttpServer
1448 1448
1449 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) 1449 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1450 { 1450 {
1451 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); 1451 int responsecode;
1452 int responsecode = (int)responsedata["int_response_code"]; 1452 string responseString;
1453 string responseString = (string)responsedata["str_response_string"]; 1453 string contentType;
1454 string contentType = (string)responsedata["content_type"]; 1454
1455 if (responsedata == null)
1456 {
1457 responsecode = 500;
1458 responseString = "No response could be obtained";
1459 contentType = "text/plain";
1460 responsedata = new Hashtable();
1461 }
1462 else
1463 {
1464 try
1465 {
1466 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
1467 responsecode = (int)responsedata["int_response_code"];
1468 responseString = (string)responsedata["str_response_string"];
1469 contentType = (string)responsedata["content_type"];
1470 }
1471 catch
1472 {
1473 responsecode = 500;
1474 responseString = "No response could be obtained";
1475 contentType = "text/plain";
1476 responsedata = new Hashtable();
1477 }
1478 }
1455 1479
1456 if (responsedata.ContainsKey("error_status_text")) 1480 if (responsedata.ContainsKey("error_status_text"))
1457 { 1481 {
@@ -1628,7 +1652,9 @@ namespace OpenSim.Framework.Servers.HttpServer
1628 1652
1629 public void httpServerException(object source, Exception exception) 1653 public void httpServerException(object source, Exception exception)
1630 { 1654 {
1631 m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); 1655 if (source.ToString() == "HttpServer.HttpListener" && exception.ToString().StartsWith("Mono.Security.Protocol.Tls.TlsException"))
1656 return;
1657 m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
1632 /* 1658 /*
1633 if (HTTPDRunning)// && NotSocketErrors > 5) 1659 if (HTTPDRunning)// && NotSocketErrors > 5)
1634 { 1660 {
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index 3089351..c24a000 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -45,17 +45,28 @@ namespace OpenSim.Framework.Servers.HttpServer
45 public NoEventsMethod NoEvents; 45 public NoEventsMethod NoEvents;
46 public RequestMethod Request; 46 public RequestMethod Request;
47 public UUID Id; 47 public UUID Id;
48 public int TimeOutms;
49 public EventType Type;
50
51 public enum EventType : int
52 {
53 Normal = 0,
54 LslHttp = 1,
55 Inventory = 2
56 }
48 57
49 public PollServiceEventArgs( 58 public PollServiceEventArgs(
50 RequestMethod pRequest, 59 RequestMethod pRequest,
51 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, 60 HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
52 UUID pId) 61 UUID pId, int pTimeOutms)
53 { 62 {
54 Request = pRequest; 63 Request = pRequest;
55 HasEvents = pHasEvents; 64 HasEvents = pHasEvents;
56 GetEvents = pGetEvents; 65 GetEvents = pGetEvents;
57 NoEvents = pNoEvents; 66 NoEvents = pNoEvents;
58 Id = pId; 67 Id = pId;
68 TimeOutms = pTimeOutms;
69 Type = EventType.Normal;
59 } 70 }
60 } 71 }
61} \ No newline at end of file 72}
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 8d50151..a1dee4e 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -34,14 +34,18 @@ using HttpServer;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Monitoring; 35using OpenSim.Framework.Monitoring;
36 36
37
38/*
37namespace OpenSim.Framework.Servers.HttpServer 39namespace OpenSim.Framework.Servers.HttpServer
38{ 40{
41
39 public class PollServiceRequestManager 42 public class PollServiceRequestManager
40 { 43 {
41// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 45
43 private readonly BaseHttpServer m_server; 46 private readonly BaseHttpServer m_server;
44 private static Queue m_requests = Queue.Synchronized(new Queue()); 47 private static Queue m_requests = Queue.Synchronized(new Queue());
48 private static ManualResetEvent m_ev = new ManualResetEvent(false);
45 private uint m_WorkerThreadCount = 0; 49 private uint m_WorkerThreadCount = 0;
46 private Thread[] m_workerThreads; 50 private Thread[] m_workerThreads;
47 private PollServiceWorkerThread[] m_PollServiceWorkerThreads; 51 private PollServiceWorkerThread[] m_PollServiceWorkerThreads;
@@ -67,7 +71,6 @@ namespace OpenSim.Framework.Servers.HttpServer
67 ThreadPriority.Normal, 71 ThreadPriority.Normal,
68 false, 72 false,
69 true, 73 true,
70 null,
71 int.MaxValue); 74 int.MaxValue);
72 } 75 }
73 76
@@ -77,7 +80,6 @@ namespace OpenSim.Framework.Servers.HttpServer
77 ThreadPriority.Normal, 80 ThreadPriority.Normal,
78 false, 81 false,
79 true, 82 true,
80 null,
81 1000 * 60 * 10); 83 1000 * 60 * 10);
82 } 84 }
83 85
@@ -91,15 +93,17 @@ namespace OpenSim.Framework.Servers.HttpServer
91 { 93 {
92 lock (m_requests) 94 lock (m_requests)
93 m_requests.Enqueue(req); 95 m_requests.Enqueue(req);
96 m_ev.Set();
94 } 97 }
95 98
96 public void ThreadStart() 99 public void ThreadStart()
97 { 100 {
98 while (m_running) 101 while (m_running)
99 { 102 {
103 m_ev.WaitOne(1000);
104 m_ev.Reset();
100 Watchdog.UpdateThread(); 105 Watchdog.UpdateThread();
101 ProcessQueuedRequests(); 106 ProcessQueuedRequests();
102 Thread.Sleep(1000);
103 } 107 }
104 } 108 }
105 109
@@ -141,8 +145,9 @@ namespace OpenSim.Framework.Servers.HttpServer
141 foreach (object o in m_requests) 145 foreach (object o in m_requests)
142 { 146 {
143 PollServiceHttpRequest req = (PollServiceHttpRequest) o; 147 PollServiceHttpRequest req = (PollServiceHttpRequest) o;
144 PollServiceWorkerThread.DoHTTPGruntWork( 148 m_server.DoHTTPGruntWork(
145 m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); 149 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
150 new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
146 } 151 }
147 152
148 m_requests.Clear(); 153 m_requests.Clear();
@@ -151,8 +156,279 @@ namespace OpenSim.Framework.Servers.HttpServer
151 { 156 {
152 t.Abort(); 157 t.Abort();
153 } 158 }
154
155 m_running = false; 159 m_running = false;
156 } 160 }
157 } 161 }
158} \ No newline at end of file 162}
163 */
164
165using System.IO;
166using System.Text;
167using System.Collections.Generic;
168
169namespace OpenSim.Framework.Servers.HttpServer
170{
171 public class PollServiceRequestManager
172 {
173 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
174
175 private readonly BaseHttpServer m_server;
176
177 private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
178 private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>();
179 private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>();
180
181 private uint m_WorkerThreadCount = 0;
182 private Thread[] m_workerThreads;
183 private Thread m_retrysThread;
184
185 private bool m_running = true;
186 private int slowCount = 0;
187
188// private int m_timeout = 1000; // increase timeout 250; now use the event one
189
190 public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
191 {
192 m_server = pSrv;
193 m_WorkerThreadCount = pWorkerThreadCount;
194 m_workerThreads = new Thread[m_WorkerThreadCount];
195
196 //startup worker threads
197 for (uint i = 0; i < m_WorkerThreadCount; i++)
198 {
199 m_workerThreads[i]
200 = Watchdog.StartThread(
201 PoolWorkerJob,
202 String.Format("PollServiceWorkerThread{0}", i),
203 ThreadPriority.Normal,
204 false,
205 true,
206 null,
207 int.MaxValue);
208 }
209
210 m_retrysThread = Watchdog.StartThread(
211 this.CheckRetries,
212 "PollServiceWatcherThread",
213 ThreadPriority.Normal,
214 false,
215 true,
216 null,
217 1000 * 60 * 10);
218 }
219
220
221 private void ReQueueEvent(PollServiceHttpRequest req)
222 {
223 if (m_running)
224 {
225 lock (m_retryRequests)
226 m_retryRequests.Enqueue(req);
227 }
228 }
229
230 public void Enqueue(PollServiceHttpRequest req)
231 {
232 if (m_running)
233 {
234 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LslHttp ||
235 req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Inventory)
236 {
237 m_requests.Enqueue(req);
238 }
239 else
240 {
241 lock (m_slowRequests)
242 m_slowRequests.Enqueue(req);
243 }
244 }
245 }
246
247 private void CheckRetries()
248 {
249 while (m_running)
250 {
251 Thread.Sleep(100); // let the world move .. back to faster rate
252 Watchdog.UpdateThread();
253 lock (m_retryRequests)
254 {
255 while (m_retryRequests.Count > 0 && m_running)
256 m_requests.Enqueue(m_retryRequests.Dequeue());
257 }
258 slowCount++;
259 if (slowCount >= 10)
260 {
261 slowCount = 0;
262
263 lock (m_slowRequests)
264 {
265 while (m_slowRequests.Count > 0 && m_running)
266 m_requests.Enqueue(m_slowRequests.Dequeue());
267 }
268 }
269 }
270 }
271
272 ~PollServiceRequestManager()
273 {
274 m_running = false;
275// m_timeout = -10000; // cause all to expire
276 Thread.Sleep(1000); // let the world move
277
278 foreach (Thread t in m_workerThreads)
279 {
280 try
281 {
282 t.Abort();
283 }
284 catch
285 {
286 }
287 }
288
289 try
290 {
291 foreach (PollServiceHttpRequest req in m_retryRequests)
292 {
293 DoHTTPGruntWork(m_server,req,
294 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
295 }
296 }
297 catch
298 {
299 }
300
301 PollServiceHttpRequest wreq;
302 m_retryRequests.Clear();
303
304 lock (m_slowRequests)
305 {
306 while (m_slowRequests.Count > 0 && m_running)
307 m_requests.Enqueue(m_slowRequests.Dequeue());
308 }
309
310 while (m_requests.Count() > 0)
311 {
312 try
313 {
314 wreq = m_requests.Dequeue(0);
315 DoHTTPGruntWork(m_server,wreq,
316 wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
317 }
318 catch
319 {
320 }
321 }
322
323 m_requests.Clear();
324 }
325
326 // work threads
327
328 private void PoolWorkerJob()
329 {
330 PollServiceHttpRequest req;
331 StreamReader str;
332
333// while (true)
334 while (m_running)
335 {
336 req = m_requests.Dequeue(5000);
337
338 Watchdog.UpdateThread();
339 if (req != null)
340 {
341 try
342 {
343 if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
344 {
345 try
346 {
347 str = new StreamReader(req.Request.Body);
348 }
349 catch (System.ArgumentException)
350 {
351 // Stream was not readable means a child agent
352 // was closed due to logout, leaving the
353 // Event Queue request orphaned.
354 continue;
355 }
356
357 try
358 {
359 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
360 DoHTTPGruntWork(m_server, req, responsedata);
361 }
362 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
363 {
364 // Ignore it, no need to reply
365 }
366
367 str.Close();
368
369 }
370 else
371 {
372// if ((Environment.TickCount - req.RequestTime) > m_timeout)
373
374 if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
375 {
376 DoHTTPGruntWork(m_server, req,
377 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
378 }
379 else
380 {
381 ReQueueEvent(req);
382 }
383 }
384 }
385 catch (Exception e)
386 {
387 m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
388 }
389 }
390 }
391 }
392
393 // DoHTTPGruntWork changed, not sending response
394 // do the same work around as core
395
396 internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
397 {
398 OSHttpResponse response
399 = new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
400
401 byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
402
403 response.SendChunked = false;
404 response.ContentLength64 = buffer.Length;
405 response.ContentEncoding = Encoding.UTF8;
406
407 try
408 {
409 response.OutputStream.Write(buffer, 0, buffer.Length);
410 }
411 catch (Exception ex)
412 {
413 m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
414 }
415 finally
416 {
417 //response.OutputStream.Close();
418 try
419 {
420 response.OutputStream.Flush();
421 response.Send();
422
423 //if (!response.KeepAlive && response.ReuseContext)
424 // response.FreeContext();
425 }
426 catch (Exception e)
427 {
428 m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
429 }
430 }
431 }
432 }
433}
434
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
index 5adbcd1..1c529b6 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs
@@ -25,6 +25,8 @@
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/* Ubit work moved to PollServiceRequestManager
29
28using System; 30using System;
29using System.Collections; 31using System.Collections;
30using System.Collections.Generic; 32using System.Collections.Generic;
@@ -90,8 +92,15 @@ namespace OpenSim.Framework.Servers.HttpServer
90 continue; 92 continue;
91 } 93 }
92 94
93 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); 95 try
94 DoHTTPGruntWork(m_server, req, responsedata); 96 {
97 Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
98 DoHTTPGruntWork(m_server, req, responsedata);
99 }
100 catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
101 {
102 // Ignore it, no need to reply
103 }
95 } 104 }
96 else 105 else
97 { 106 {
@@ -162,4 +171,5 @@ namespace OpenSim.Framework.Servers.HttpServer
162 } 171 }
163 } 172 }
164 } 173 }
165} \ No newline at end of file 174}
175*/ \ No newline at end of file