diff options
Diffstat (limited to 'OpenSim/Framework/Servers')
3 files changed, 116 insertions, 6 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 799ab80..1363eab 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -459,7 +459,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
459 | } | 459 | } |
460 | 460 | ||
461 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); | 461 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); |
462 | resp.ReuseContext = true; | 462 | resp.ReuseContext = false; |
463 | HandleRequest(req, resp); | 463 | HandleRequest(req, resp); |
464 | 464 | ||
465 | // !!!HACK ALERT!!! | 465 | // !!!HACK ALERT!!! |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index 6aa9479..5bd63a6 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | ||
30 | using System.Reflection; | 31 | using System.Reflection; |
31 | using System.Text; | 32 | using System.Text; |
32 | using HttpServer; | 33 | using HttpServer; |
@@ -44,6 +45,24 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
44 | public readonly IHttpRequest Request; | 45 | public readonly IHttpRequest Request; |
45 | public readonly int RequestTime; | 46 | public readonly int RequestTime; |
46 | public readonly UUID RequestID; | 47 | public readonly UUID RequestID; |
48 | public int contextHash; | ||
49 | |||
50 | private void GenContextHash() | ||
51 | { | ||
52 | Random rnd = new Random(); | ||
53 | contextHash = 0; | ||
54 | if (Request.Headers["remote_addr"] != null) | ||
55 | contextHash = (Request.Headers["remote_addr"]).GetHashCode() << 16; | ||
56 | else | ||
57 | contextHash = rnd.Next() << 16; | ||
58 | if (Request.Headers["remote_port"] != null) | ||
59 | { | ||
60 | string[] strPorts = Request.Headers["remote_port"].Split(new char[] { ',' }); | ||
61 | contextHash += Int32.Parse(strPorts[0]); | ||
62 | } | ||
63 | else | ||
64 | contextHash += rnd.Next() & 0xffff; | ||
65 | } | ||
47 | 66 | ||
48 | public PollServiceHttpRequest( | 67 | public PollServiceHttpRequest( |
49 | PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) | 68 | PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) |
@@ -53,6 +72,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
53 | Request = pRequest; | 72 | Request = pRequest; |
54 | RequestTime = System.Environment.TickCount; | 73 | RequestTime = System.Environment.TickCount; |
55 | RequestID = UUID.Random(); | 74 | RequestID = UUID.Random(); |
75 | GenContextHash(); | ||
56 | } | 76 | } |
57 | 77 | ||
58 | internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) | 78 | internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) |
@@ -65,6 +85,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
65 | response.SendChunked = false; | 85 | response.SendChunked = false; |
66 | response.ContentLength64 = buffer.Length; | 86 | response.ContentLength64 = buffer.Length; |
67 | response.ContentEncoding = Encoding.UTF8; | 87 | response.ContentEncoding = Encoding.UTF8; |
88 | response.ReuseContext = false; | ||
68 | 89 | ||
69 | try | 90 | try |
70 | { | 91 | { |
@@ -93,5 +114,44 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
93 | PollServiceArgs.RequestsHandled++; | 114 | PollServiceArgs.RequestsHandled++; |
94 | } | 115 | } |
95 | } | 116 | } |
117 | |||
118 | internal void DoHTTPstop(BaseHttpServer server) | ||
119 | { | ||
120 | OSHttpResponse response | ||
121 | = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); | ||
122 | |||
123 | response.SendChunked = false; | ||
124 | response.ContentLength64 = 0; | ||
125 | response.ContentEncoding = Encoding.UTF8; | ||
126 | response.ReuseContext = false; | ||
127 | response.KeepAlive = false; | ||
128 | response.SendChunked = false; | ||
129 | response.StatusCode = 503; | ||
130 | |||
131 | try | ||
132 | { | ||
133 | response.OutputStream.Flush(); | ||
134 | response.Send(); | ||
135 | } | ||
136 | catch (Exception e) | ||
137 | { | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
142 | class PollServiceHttpRequestComparer : IEqualityComparer<PollServiceHttpRequest> | ||
143 | { | ||
144 | public bool Equals(PollServiceHttpRequest b1, PollServiceHttpRequest b2) | ||
145 | { | ||
146 | if (b1.contextHash != b2.contextHash) | ||
147 | return false; | ||
148 | bool b = Object.ReferenceEquals(b1.HttpContext, b2.HttpContext); | ||
149 | return b; | ||
150 | } | ||
151 | |||
152 | public int GetHashCode(PollServiceHttpRequest b2) | ||
153 | { | ||
154 | return (int)b2.contextHash; | ||
155 | } | ||
96 | } | 156 | } |
97 | } \ No newline at end of file | 157 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index e75b705..b56ade8 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -46,6 +46,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
46 | 46 | ||
47 | private readonly BaseHttpServer m_server; | 47 | private readonly BaseHttpServer m_server; |
48 | 48 | ||
49 | private Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>> m_bycontext; | ||
49 | private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); | 50 | private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>(); |
50 | private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); | 51 | private static Queue<PollServiceHttpRequest> m_slowRequests = new Queue<PollServiceHttpRequest>(); |
51 | private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>(); | 52 | private static Queue<PollServiceHttpRequest> m_retryRequests = new Queue<PollServiceHttpRequest>(); |
@@ -65,6 +66,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
65 | m_WorkerThreadCount = pWorkerThreadCount; | 66 | m_WorkerThreadCount = pWorkerThreadCount; |
66 | m_workerThreads = new Thread[m_WorkerThreadCount]; | 67 | m_workerThreads = new Thread[m_WorkerThreadCount]; |
67 | 68 | ||
69 | PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer(); | ||
70 | m_bycontext = new Dictionary<PollServiceHttpRequest, Queue<PollServiceHttpRequest>>(preqCp); | ||
71 | |||
68 | STPStartInfo startInfo = new STPStartInfo(); | 72 | STPStartInfo startInfo = new STPStartInfo(); |
69 | startInfo.IdleTimeout = 30000; | 73 | startInfo.IdleTimeout = 30000; |
70 | startInfo.MaxWorkerThreads = 15; | 74 | startInfo.MaxWorkerThreads = 15; |
@@ -114,6 +118,45 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
114 | 118 | ||
115 | public void Enqueue(PollServiceHttpRequest req) | 119 | public void Enqueue(PollServiceHttpRequest req) |
116 | { | 120 | { |
121 | lock (m_bycontext) | ||
122 | { | ||
123 | Queue<PollServiceHttpRequest> ctxQeueue; | ||
124 | if (m_bycontext.TryGetValue(req, out ctxQeueue)) | ||
125 | { | ||
126 | ctxQeueue.Enqueue(req); | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | ctxQeueue = new Queue<PollServiceHttpRequest>(); | ||
131 | m_bycontext[req] = ctxQeueue; | ||
132 | EnqueueInt(req); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | public void byContextDequeue(PollServiceHttpRequest req) | ||
138 | { | ||
139 | Queue<PollServiceHttpRequest> ctxQeueue; | ||
140 | lock (m_bycontext) | ||
141 | { | ||
142 | if (m_bycontext.TryGetValue(req, out ctxQeueue)) | ||
143 | { | ||
144 | if (ctxQeueue.Count > 0) | ||
145 | { | ||
146 | PollServiceHttpRequest newreq = ctxQeueue.Dequeue(); | ||
147 | EnqueueInt(newreq); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | m_bycontext.Remove(req); | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | public void EnqueueInt(PollServiceHttpRequest req) | ||
159 | { | ||
117 | if (m_running) | 160 | if (m_running) |
118 | { | 161 | { |
119 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll) | 162 | if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll) |
@@ -161,12 +204,17 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
161 | foreach (Thread t in m_workerThreads) | 204 | foreach (Thread t in m_workerThreads) |
162 | Watchdog.AbortThread(t.ManagedThreadId); | 205 | Watchdog.AbortThread(t.ManagedThreadId); |
163 | 206 | ||
207 | // any entry in m_bycontext should have a active request on the other queues | ||
208 | // so just delete contents to easy GC | ||
209 | foreach (Queue<PollServiceHttpRequest> qu in m_bycontext.Values) | ||
210 | qu.Clear(); | ||
211 | m_bycontext.Clear(); | ||
212 | |||
164 | try | 213 | try |
165 | { | 214 | { |
166 | foreach (PollServiceHttpRequest req in m_retryRequests) | 215 | foreach (PollServiceHttpRequest req in m_retryRequests) |
167 | { | 216 | { |
168 | req.DoHTTPGruntWork(m_server, | 217 | req.DoHTTPstop(m_server); |
169 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||
170 | } | 218 | } |
171 | } | 219 | } |
172 | catch | 220 | catch |
@@ -178,7 +226,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
178 | 226 | ||
179 | lock (m_slowRequests) | 227 | lock (m_slowRequests) |
180 | { | 228 | { |
181 | while (m_slowRequests.Count > 0 && m_running) | 229 | while (m_slowRequests.Count > 0) |
182 | m_requests.Enqueue(m_slowRequests.Dequeue()); | 230 | m_requests.Enqueue(m_slowRequests.Dequeue()); |
183 | } | 231 | } |
184 | 232 | ||
@@ -187,8 +235,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
187 | try | 235 | try |
188 | { | 236 | { |
189 | wreq = m_requests.Dequeue(0); | 237 | wreq = m_requests.Dequeue(0); |
190 | wreq.DoHTTPGruntWork(m_server, | 238 | wreq.DoHTTPstop(m_server); |
191 | wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id)); | ||
192 | } | 239 | } |
193 | catch | 240 | catch |
194 | { | 241 | { |
@@ -220,6 +267,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
220 | try | 267 | try |
221 | { | 268 | { |
222 | req.DoHTTPGruntWork(m_server, responsedata); | 269 | req.DoHTTPGruntWork(m_server, responsedata); |
270 | byContextDequeue(req); | ||
223 | } | 271 | } |
224 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | 272 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream |
225 | { | 273 | { |
@@ -233,6 +281,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
233 | try | 281 | try |
234 | { | 282 | { |
235 | req.DoHTTPGruntWork(m_server, responsedata); | 283 | req.DoHTTPGruntWork(m_server, responsedata); |
284 | byContextDequeue(req); | ||
236 | } | 285 | } |
237 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream | 286 | catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream |
238 | { | 287 | { |
@@ -249,6 +298,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
249 | { | 298 | { |
250 | req.DoHTTPGruntWork(m_server, | 299 | req.DoHTTPGruntWork(m_server, |
251 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | 300 | req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); |
301 | byContextDequeue(req); | ||
252 | } | 302 | } |
253 | else | 303 | else |
254 | { | 304 | { |