diff options
author | Teravus Ovares | 2009-07-29 02:15:45 +0000 |
---|---|---|
committer | Teravus Ovares | 2009-07-29 02:15:45 +0000 |
commit | 032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35 (patch) | |
tree | 63d21eaa99b003b47f8eceb09e21b6c4f32ae4f7 /OpenSim/Framework/Servers | |
parent | Add the missing block to the alert message (diff) | |
download | opensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.zip opensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.gz opensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.bz2 opensim-SC_OLD-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.xz |
* Adds the ability to have a thread efficient long poll service (such as the eventqueue)
* If this doesn't melt the Http Server, this will significantly reduce the number of threads in use on regions with many users.
* Adds AddPollServiceHTTPHandler, and RemovePollServiceHTTPHandler to BaseHttpServer
* Generic enough to be used for many long poll services, not only the EventQueue.
Diffstat (limited to 'OpenSim/Framework/Servers')
7 files changed, 442 insertions, 5 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 4532e76..369d7d4 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -64,6 +64,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
64 | protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>(); | 64 | protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>(); |
65 | protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>(); | 65 | protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>(); |
66 | 66 | ||
67 | protected Dictionary<string, PollServiceEventArgs> m_pollHandlers = | ||
68 | new Dictionary<string, PollServiceEventArgs>(); | ||
69 | |||
67 | protected uint m_port; | 70 | protected uint m_port; |
68 | protected uint m_sslport; | 71 | protected uint m_sslport; |
69 | protected bool m_ssl; | 72 | protected bool m_ssl; |
@@ -72,6 +75,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
72 | 75 | ||
73 | protected IPAddress m_listenIPAddress = IPAddress.Any; | 76 | protected IPAddress m_listenIPAddress = IPAddress.Any; |
74 | 77 | ||
78 | private PollServiceRequestManager m_PollServiceManager; | ||
79 | |||
75 | public uint SSLPort | 80 | public uint SSLPort |
76 | { | 81 | { |
77 | get { return m_sslport; } | 82 | get { return m_sslport; } |
@@ -189,6 +194,26 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
189 | return false; | 194 | return false; |
190 | } | 195 | } |
191 | 196 | ||
197 | public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args) | ||
198 | { | ||
199 | bool pollHandlerResult = false; | ||
200 | lock (m_pollHandlers) | ||
201 | { | ||
202 | if (!m_pollHandlers.ContainsKey( methodName)) | ||
203 | { | ||
204 | m_pollHandlers.Add(methodName,args); | ||
205 | pollHandlerResult = true; | ||
206 | |||
207 | } | ||
208 | } | ||
209 | |||
210 | if (pollHandlerResult) | ||
211 | return AddHTTPHandler(methodName, handler); | ||
212 | |||
213 | return false; | ||
214 | |||
215 | } | ||
216 | |||
192 | // Note that the agent string is provided simply to differentiate | 217 | // Note that the agent string is provided simply to differentiate |
193 | // the handlers - it is NOT required to be an actual agent header | 218 | // the handlers - it is NOT required to be an actual agent header |
194 | // value. | 219 | // value. |
@@ -230,8 +255,19 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
230 | { | 255 | { |
231 | IHttpClientContext context = (IHttpClientContext)source; | 256 | IHttpClientContext context = (IHttpClientContext)source; |
232 | IHttpRequest request = args.Request; | 257 | IHttpRequest request = args.Request; |
258 | |||
233 | 259 | ||
234 | OnHandleRequestIOThread(context,request); | 260 | PollServiceEventArgs psEvArgs; |
261 | if (TryGetPollServiceHTTPHandler(request.UriPath.ToString(), out psEvArgs)) | ||
262 | { | ||
263 | |||
264 | m_PollServiceManager.Enqueue(new PollServiceHttpRequest(psEvArgs, context, request)); | ||
265 | //DoHTTPGruntWork(psEvArgs.NoEvents(),new OSHttpResponse(new HttpResponse(context, request))); | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | OnHandleRequestIOThread(context, request); | ||
270 | } | ||
235 | 271 | ||
236 | } | 272 | } |
237 | 273 | ||
@@ -341,7 +377,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
341 | string requestBody = reader.ReadToEnd(); | 377 | string requestBody = reader.ReadToEnd(); |
342 | 378 | ||
343 | reader.Close(); | 379 | reader.Close(); |
344 | requestStream.Close(); | 380 | //requestStream.Close(); |
345 | 381 | ||
346 | Hashtable keysvals = new Hashtable(); | 382 | Hashtable keysvals = new Hashtable(); |
347 | Hashtable headervals = new Hashtable(); | 383 | Hashtable headervals = new Hashtable(); |
@@ -527,6 +563,36 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
527 | } | 563 | } |
528 | } | 564 | } |
529 | 565 | ||
566 | private bool TryGetPollServiceHTTPHandler(string handlerKey, out PollServiceEventArgs oServiceEventArgs) | ||
567 | { | ||
568 | string bestMatch = null; | ||
569 | |||
570 | lock (m_pollHandlers) | ||
571 | { | ||
572 | foreach (string pattern in m_pollHandlers.Keys) | ||
573 | { | ||
574 | if (handlerKey.StartsWith(pattern)) | ||
575 | { | ||
576 | if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) | ||
577 | { | ||
578 | bestMatch = pattern; | ||
579 | } | ||
580 | } | ||
581 | } | ||
582 | |||
583 | if (String.IsNullOrEmpty(bestMatch)) | ||
584 | { | ||
585 | oServiceEventArgs = null; | ||
586 | return false; | ||
587 | } | ||
588 | else | ||
589 | { | ||
590 | oServiceEventArgs = m_pollHandlers[bestMatch]; | ||
591 | return true; | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | |||
530 | private bool TryGetHTTPHandler(string handlerKey, out GenericHTTPMethod HTTPHandler) | 596 | private bool TryGetHTTPHandler(string handlerKey, out GenericHTTPMethod HTTPHandler) |
531 | { | 597 | { |
532 | //m_log.DebugFormat("[BASE HTTP HANDLER]: Looking for HTTP handler for {0}", handlerKey); | 598 | //m_log.DebugFormat("[BASE HTTP HANDLER]: Looking for HTTP handler for {0}", handlerKey); |
@@ -822,7 +888,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
822 | { | 888 | { |
823 | response.Send(); | 889 | response.Send(); |
824 | response.OutputStream.Flush(); | 890 | response.OutputStream.Flush(); |
825 | response.OutputStream.Close(); | 891 | //response.OutputStream.Close(); |
826 | } | 892 | } |
827 | catch (IOException e) | 893 | catch (IOException e) |
828 | { | 894 | { |
@@ -1237,7 +1303,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1237 | } | 1303 | } |
1238 | } | 1304 | } |
1239 | 1305 | ||
1240 | private static void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) | 1306 | internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) |
1241 | { | 1307 | { |
1242 | //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); | 1308 | //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); |
1243 | int responsecode = (int)responsedata["int_response_code"]; | 1309 | int responsecode = (int)responsedata["int_response_code"]; |
@@ -1261,7 +1327,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1261 | } | 1327 | } |
1262 | //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this | 1328 | //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this |
1263 | //and should check for NullReferenceExceptions | 1329 | //and should check for NullReferenceExceptions |
1264 | 1330 | ||
1265 | if (string.IsNullOrEmpty(contentType)) | 1331 | if (string.IsNullOrEmpty(contentType)) |
1266 | { | 1332 | { |
1267 | contentType = "text/html"; | 1333 | contentType = "text/html"; |
@@ -1402,6 +1468,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1402 | //m_workerThread.Start(); | 1468 | //m_workerThread.Start(); |
1403 | //ThreadTracker.Add(m_workerThread); | 1469 | //ThreadTracker.Add(m_workerThread); |
1404 | StartHTTP(); | 1470 | StartHTTP(); |
1471 | |||
1472 | |||
1405 | } | 1473 | } |
1406 | 1474 | ||
1407 | private void StartHTTP() | 1475 | private void StartHTTP() |
@@ -1434,6 +1502,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1434 | m_httpListener2.RequestReceived += OnRequest; | 1502 | m_httpListener2.RequestReceived += OnRequest; |
1435 | //m_httpListener.Start(); | 1503 | //m_httpListener.Start(); |
1436 | m_httpListener2.Start(64); | 1504 | m_httpListener2.Start(64); |
1505 | |||
1506 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events | ||
1507 | m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000); | ||
1437 | HTTPDRunning = true; | 1508 | HTTPDRunning = true; |
1438 | 1509 | ||
1439 | //HttpListenerContext context; | 1510 | //HttpListenerContext context; |
@@ -1514,6 +1585,20 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1514 | } | 1585 | } |
1515 | } | 1586 | } |
1516 | 1587 | ||
1588 | public void RemovePollServiceHTTPHandler(string httpMethod, string path) | ||
1589 | { | ||
1590 | lock (m_pollHandlers) | ||
1591 | { | ||
1592 | if (m_pollHandlers.ContainsKey(httpMethod)) | ||
1593 | { | ||
1594 | m_pollHandlers.Remove(httpMethod); | ||
1595 | } | ||
1596 | } | ||
1597 | |||
1598 | RemoveHTTPHandler(httpMethod, path); | ||
1599 | |||
1600 | } | ||
1601 | |||
1517 | public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) | 1602 | public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler) |
1518 | { | 1603 | { |
1519 | try | 1604 | try |
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs index c415dfb..9095831 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs | |||
@@ -74,6 +74,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
74 | /// </returns> | 74 | /// </returns> |
75 | bool AddHTTPHandler(string methodName, GenericHTTPMethod handler); | 75 | bool AddHTTPHandler(string methodName, GenericHTTPMethod handler); |
76 | 76 | ||
77 | |||
78 | bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args); | ||
79 | |||
77 | /// <summary> | 80 | /// <summary> |
78 | /// Adds a LLSD handler, yay. | 81 | /// Adds a LLSD handler, yay. |
79 | /// </summary> | 82 | /// </summary> |
@@ -114,6 +117,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
114 | /// <param name="httpMethod"></param> | 117 | /// <param name="httpMethod"></param> |
115 | /// <param name="path"></param> | 118 | /// <param name="path"></param> |
116 | void RemoveHTTPHandler(string httpMethod, string path); | 119 | void RemoveHTTPHandler(string httpMethod, string path); |
120 | |||
121 | void RemovePollServiceHTTPHandler(string httpMethod, string path); | ||
117 | 122 | ||
118 | bool RemoveLLSDHandler(string path, LLSDMethod handler); | 123 | bool RemoveLLSDHandler(string path, LLSDMethod handler); |
119 | 124 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs new file mode 100644 index 0000000..fed490e --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs | |||
@@ -0,0 +1,53 @@ | |||
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 OpenSimulator 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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using OpenMetaverse; | ||
31 | namespace OpenSim.Framework.Servers.HttpServer | ||
32 | { | ||
33 | public delegate bool HasEventsMethod(UUID pId); | ||
34 | |||
35 | public delegate Hashtable GetEventsMethod(UUID pId, string request); | ||
36 | |||
37 | public delegate Hashtable NoEventsMethod(); | ||
38 | |||
39 | public class PollServiceEventArgs : EventArgs | ||
40 | { | ||
41 | public HasEventsMethod HasEvents; | ||
42 | public GetEventsMethod GetEvents; | ||
43 | public NoEventsMethod NoEvents; | ||
44 | public UUID Id; | ||
45 | public PollServiceEventArgs(HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId) | ||
46 | { | ||
47 | HasEvents = pHasEvents; | ||
48 | GetEvents = pGetEvents; | ||
49 | NoEvents = pNoEvents; | ||
50 | Id = pId; | ||
51 | } | ||
52 | } | ||
53 | } | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs new file mode 100644 index 0000000..ff7c1e8 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs | |||
@@ -0,0 +1,48 @@ | |||
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 OpenSimulator 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 | |||
28 | using System; | ||
29 | using HttpServer; | ||
30 | |||
31 | namespace OpenSim.Framework.Servers.HttpServer | ||
32 | { | ||
33 | |||
34 | public class PollServiceHttpRequest | ||
35 | { | ||
36 | public readonly PollServiceEventArgs PollServiceArgs; | ||
37 | public readonly IHttpClientContext HttpContext; | ||
38 | public readonly IHttpRequest Request; | ||
39 | public readonly int RequestTime; | ||
40 | public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) | ||
41 | { | ||
42 | PollServiceArgs = pPollServiceArgs; | ||
43 | HttpContext = pHttpContext; | ||
44 | Request = pRequest; | ||
45 | RequestTime = System.Environment.TickCount; | ||
46 | } | ||
47 | } | ||
48 | } | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs new file mode 100644 index 0000000..7f632cf --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -0,0 +1,145 @@ | |||
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 OpenSimulator 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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Threading; | ||
31 | using HttpServer; | ||
32 | |||
33 | namespace OpenSim.Framework.Servers.HttpServer | ||
34 | { | ||
35 | public class PollServiceRequestManager | ||
36 | { | ||
37 | private readonly BaseHttpServer m_server; | ||
38 | private static Queue m_requests = Queue.Synchronized(new Queue()); | ||
39 | private uint m_WorkerThreadCount = 0; | ||
40 | private Thread[] m_workerThreads; | ||
41 | private PollServiceWorkerThread[] m_PollServiceWorkerThreads; | ||
42 | private Thread m_watcherThread; | ||
43 | private bool m_running = true; | ||
44 | |||
45 | |||
46 | |||
47 | public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) | ||
48 | { | ||
49 | m_server = pSrv; | ||
50 | m_WorkerThreadCount = pWorkerThreadCount; | ||
51 | m_workerThreads = new Thread[m_WorkerThreadCount]; | ||
52 | m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount]; | ||
53 | m_watcherThread = new Thread(ThreadStart); | ||
54 | |||
55 | |||
56 | //startup worker threads | ||
57 | for (uint i=0;i<m_WorkerThreadCount;i++) | ||
58 | { | ||
59 | m_PollServiceWorkerThreads[i] = new PollServiceWorkerThread(m_server, pTimeout); | ||
60 | m_PollServiceWorkerThreads[i].ReQueue += ReQueueEvent; | ||
61 | |||
62 | m_workerThreads[i] = new Thread( m_PollServiceWorkerThreads[i].ThreadStart); | ||
63 | m_workerThreads[i].Name = String.Format("PollServiceWorkerThread{0}",i); | ||
64 | //Can't add to thread Tracker here Referencing OpenSim.Framework creates circular reference | ||
65 | m_workerThreads[i].Start(); | ||
66 | |||
67 | } | ||
68 | //start watcher threads | ||
69 | m_watcherThread.Name = "PollServiceWatcherThread"; | ||
70 | m_watcherThread.Start(); | ||
71 | |||
72 | |||
73 | } | ||
74 | |||
75 | internal void ReQueueEvent(PollServiceHttpRequest req) | ||
76 | { | ||
77 | // Do accounting stuff here | ||
78 | Enqueue(req); | ||
79 | } | ||
80 | |||
81 | public void Enqueue(PollServiceHttpRequest req) | ||
82 | { | ||
83 | lock (m_requests) | ||
84 | m_requests.Enqueue(req); | ||
85 | } | ||
86 | |||
87 | public void ThreadStart(object o) | ||
88 | { | ||
89 | while (m_running) | ||
90 | { | ||
91 | ProcessQueuedRequests(); | ||
92 | Thread.Sleep(1000); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | private void ProcessQueuedRequests() | ||
97 | { | ||
98 | lock (m_requests) | ||
99 | { | ||
100 | if (m_requests.Count == 0) | ||
101 | return; | ||
102 | |||
103 | int reqperthread = (int) (m_requests.Count/m_WorkerThreadCount) + 1; | ||
104 | // For Each WorkerThread | ||
105 | for (int tc = 0; tc < m_WorkerThreadCount && m_requests.Count > 0; tc++) | ||
106 | { | ||
107 | //Loop over number of requests each thread handles. | ||
108 | for (int i=0;i<reqperthread && m_requests.Count > 0;i++) | ||
109 | { | ||
110 | try | ||
111 | { | ||
112 | m_PollServiceWorkerThreads[tc].Enqueue((PollServiceHttpRequest)m_requests.Dequeue()); | ||
113 | } | ||
114 | catch (InvalidOperationException) | ||
115 | { | ||
116 | // The queue is empty, we did our calculations wrong! | ||
117 | return; | ||
118 | } | ||
119 | |||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | } | ||
125 | |||
126 | |||
127 | |||
128 | ~PollServiceRequestManager() | ||
129 | { | ||
130 | foreach (object o in m_requests) | ||
131 | { | ||
132 | PollServiceHttpRequest req = (PollServiceHttpRequest) o; | ||
133 | m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(), new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request))); | ||
134 | } | ||
135 | |||
136 | m_requests.Clear(); | ||
137 | |||
138 | foreach (Thread t in m_workerThreads) | ||
139 | { | ||
140 | t.Abort(); | ||
141 | } | ||
142 | m_running = false; | ||
143 | } | ||
144 | } | ||
145 | } | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs new file mode 100644 index 0000000..4c0be78 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs | |||
@@ -0,0 +1,100 @@ | |||
1 | using System; | ||
2 | using System.Collections; | ||
3 | using System.Collections.Generic; | ||
4 | /* | ||
5 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
6 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions are met: | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * * Neither the name of the OpenSimulator Project nor the | ||
16 | * names of its contributors may be used to endorse or promote products | ||
17 | * derived from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
22 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | using System.IO; | ||
32 | using System.Text; | ||
33 | using HttpServer; | ||
34 | using OpenMetaverse; | ||
35 | |||
36 | namespace OpenSim.Framework.Servers.HttpServer | ||
37 | { | ||
38 | public delegate void ReQueuePollServiceItem(PollServiceHttpRequest req); | ||
39 | |||
40 | public class PollServiceWorkerThread | ||
41 | { | ||
42 | public event ReQueuePollServiceItem ReQueue; | ||
43 | |||
44 | private readonly BaseHttpServer m_server; | ||
45 | private BlockingQueue<PollServiceHttpRequest> m_request; | ||
46 | private bool m_running = true; | ||
47 | private int m_timeout = 25000; | ||
48 | |||
49 | |||
50 | |||
51 | public PollServiceWorkerThread(BaseHttpServer pSrv, int pTimeout) | ||
52 | { | ||
53 | m_request = new BlockingQueue<PollServiceHttpRequest>(); | ||
54 | m_server = pSrv; | ||
55 | m_timeout = pTimeout; | ||
56 | } | ||
57 | |||
58 | public void ThreadStart(object o) | ||
59 | { | ||
60 | Run(); | ||
61 | } | ||
62 | |||
63 | public void Run() | ||
64 | { | ||
65 | while (m_running) | ||
66 | { | ||
67 | PollServiceHttpRequest req = m_request.Dequeue(); | ||
68 | if (req.PollServiceArgs.HasEvents(req.PollServiceArgs.Id)) | ||
69 | { | ||
70 | StreamReader str = new StreamReader(req.Request.Body); | ||
71 | |||
72 | Hashtable responsedata = req.PollServiceArgs.GetEvents(req.PollServiceArgs.Id, str.ReadToEnd()); | ||
73 | m_server.DoHTTPGruntWork(responsedata, | ||
74 | new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request))); | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | if ((Environment.TickCount - req.RequestTime) > m_timeout) | ||
79 | { | ||
80 | m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(), | ||
81 | new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request))); | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | ReQueuePollServiceItem reQueueItem = ReQueue; | ||
86 | if (reQueueItem != null) | ||
87 | reQueueItem(req); | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | |||
93 | } | ||
94 | |||
95 | internal void Enqueue(PollServiceHttpRequest pPollServiceHttpRequest) | ||
96 | { | ||
97 | m_request.Enqueue(pPollServiceHttpRequest); | ||
98 | } | ||
99 | } | ||
100 | } | ||
diff --git a/OpenSim/Framework/Servers/Tests/OSHttpTests.cs b/OpenSim/Framework/Servers/Tests/OSHttpTests.cs index f7f0afa..a6a90dc 100644 --- a/OpenSim/Framework/Servers/Tests/OSHttpTests.cs +++ b/OpenSim/Framework/Servers/Tests/OSHttpTests.cs | |||
@@ -67,6 +67,7 @@ namespace OpenSim.Framework.Servers.Tests | |||
67 | public void Send(byte[] buffer) {} | 67 | public void Send(byte[] buffer) {} |
68 | public void Send(byte[] buffer, int offset, int size) {} | 68 | public void Send(byte[] buffer, int offset, int size) {} |
69 | public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {} | 69 | public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {} |
70 | public void Close() { } | ||
70 | 71 | ||
71 | public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { }; | 72 | public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { }; |
72 | /// <summary> | 73 | /// <summary> |