aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
diff options
context:
space:
mode:
authorTeravus Ovares2009-07-29 02:15:45 +0000
committerTeravus Ovares2009-07-29 02:15:45 +0000
commit032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35 (patch)
tree63d21eaa99b003b47f8eceb09e21b6c4f32ae4f7 /OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
parentAdd the missing block to the alert message (diff)
downloadopensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.zip
opensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.gz
opensim-SC-032aeb8b5d05f5f5a8ef8c6e0fe572a321717c35.tar.bz2
opensim-SC-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/HttpServer/PollServiceRequestManager.cs')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs145
1 files changed, 145 insertions, 0 deletions
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
28using System;
29using System.Collections;
30using System.Threading;
31using HttpServer;
32
33namespace 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}