1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.nio;
16
17 import java.io.IOException;
18 import java.net.InetSocketAddress;
19 import java.net.Socket;
20 import java.nio.channels.SelectionKey;
21 import java.nio.channels.ServerSocketChannel;
22 import java.nio.channels.SocketChannel;
23
24 import org.mortbay.io.Connection;
25 import org.mortbay.io.EndPoint;
26 import org.mortbay.io.nio.SelectChannelEndPoint;
27 import org.mortbay.io.nio.SelectorManager;
28 import org.mortbay.io.nio.SelectorManager.SelectSet;
29 import org.mortbay.jetty.HttpConnection;
30 import org.mortbay.jetty.Request;
31 import org.mortbay.log.Log;
32 import org.mortbay.thread.Timeout.Task;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class SelectChannelConnector extends AbstractNIOConnector
64 {
65 private transient ServerSocketChannel _acceptChannel;
66 private long _lowResourcesConnections;
67 private long _lowResourcesMaxIdleTime;
68
69 private SelectorManager _manager = new SelectorManager()
70 {
71 protected SocketChannel acceptChannel(SelectionKey key) throws IOException
72 {
73
74 SocketChannel channel = ((ServerSocketChannel)key.channel()).accept();
75 if (channel==null)
76 return null;
77 channel.configureBlocking(false);
78 Socket socket = channel.socket();
79 configure(socket);
80 return channel;
81 }
82
83 public boolean dispatch(Runnable task)
84 {
85 return getThreadPool().dispatch(task);
86 }
87
88 protected void endPointClosed(SelectChannelEndPoint endpoint)
89 {
90
91 connectionClosed((HttpConnection)endpoint.getConnection());
92 }
93
94 protected void endPointOpened(SelectChannelEndPoint endpoint)
95 {
96
97 connectionOpened((HttpConnection)endpoint.getConnection());
98 }
99
100 protected Connection newConnection(SocketChannel channel,SelectChannelEndPoint endpoint)
101 {
102 return SelectChannelConnector.this.newConnection(channel,endpoint);
103 }
104
105 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey sKey) throws IOException
106 {
107 return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey);
108 }
109 };
110
111
112
113
114
115
116 public SelectChannelConnector()
117 {
118 }
119
120
121 public void accept(int acceptorID) throws IOException
122 {
123 _manager.doSelect(acceptorID);
124 }
125
126
127 public void close() throws IOException
128 {
129 synchronized(this)
130 {
131 if(_manager.isRunning())
132 {
133 try
134 {
135 _manager.stop();
136 }
137 catch (Exception e)
138 {
139 Log.warn(e);
140 }
141 }
142 if (_acceptChannel != null)
143 _acceptChannel.close();
144 _acceptChannel = null;
145 }
146 }
147
148
149 @Override
150 public void customize(EndPoint endpoint, Request request) throws IOException
151 {
152 SelectChannelEndPoint cep = ((SelectChannelEndPoint)endpoint);
153 cep.cancelIdle();
154 request.setTimeStamp(cep.getSelectSet().getNow());
155 super.customize(endpoint, request);
156 }
157
158
159 @Override
160 public void persist(EndPoint endpoint) throws IOException
161 {
162 ((SelectChannelEndPoint)endpoint).scheduleIdle();
163 super.persist(endpoint);
164 }
165
166
167 public Object getConnection()
168 {
169 return _acceptChannel;
170 }
171
172
173 public int getLocalPort()
174 {
175 synchronized(this)
176 {
177 if (_acceptChannel==null || !_acceptChannel.isOpen())
178 return -1;
179 return _acceptChannel.socket().getLocalPort();
180 }
181 }
182
183
184 public void open() throws IOException
185 {
186 synchronized(this)
187 {
188 if (_acceptChannel == null)
189 {
190
191 _acceptChannel = ServerSocketChannel.open();
192
193
194 _acceptChannel.socket().setReuseAddress(getReuseAddress());
195 InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort());
196 _acceptChannel.socket().bind(addr,getAcceptQueueSize());
197
198
199 _acceptChannel.configureBlocking(false);
200
201 }
202 }
203 }
204
205
206 public void setMaxIdleTime(int maxIdleTime)
207 {
208 _manager.setMaxIdleTime(maxIdleTime);
209 super.setMaxIdleTime(maxIdleTime);
210 }
211
212
213
214
215
216 public long getLowResourcesConnections()
217 {
218 return _lowResourcesConnections;
219 }
220
221
222
223
224
225
226
227
228 public void setLowResourcesConnections(long lowResourcesConnections)
229 {
230 _lowResourcesConnections=lowResourcesConnections;
231 }
232
233
234
235
236
237 public long getLowResourcesMaxIdleTime()
238 {
239 return _lowResourcesMaxIdleTime;
240 }
241
242
243
244
245
246
247
248
249
250
251 public void setLowResourcesMaxIdleTime(long lowResourcesMaxIdleTime)
252 {
253 _lowResourcesMaxIdleTime=lowResourcesMaxIdleTime;
254 super.setLowResourceMaxIdleTime((int)lowResourcesMaxIdleTime);
255 }
256
257
258
259
260
261
262
263
264
265 public void setLowResourceMaxIdleTime(int lowResourcesMaxIdleTime)
266 {
267 _lowResourcesMaxIdleTime=lowResourcesMaxIdleTime;
268 super.setLowResourceMaxIdleTime(lowResourcesMaxIdleTime);
269 }
270
271
272
273
274
275
276 protected void doStart() throws Exception
277 {
278 _manager.setSelectSets(getAcceptors());
279 _manager.setMaxIdleTime(getMaxIdleTime());
280 _manager.setLowResourcesConnections(getLowResourcesConnections());
281 _manager.setLowResourcesMaxIdleTime(getLowResourcesMaxIdleTime());
282 _manager.start();
283 open();
284 _manager.register(_acceptChannel);
285 super.doStart();
286 }
287
288
289
290
291
292 protected void doStop() throws Exception
293 {
294 super.doStop();
295 }
296
297
298 protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
299 {
300 return new SelectChannelEndPoint(channel,selectSet,key)
301 {
302
303 public boolean isReadyForDispatch()
304 {
305 return super.isReadyForDispatch() && !((HttpConnection)getConnection()).getRequest().isSuspended();
306 }
307 };
308 }
309
310
311 protected Connection newConnection(SocketChannel channel,final SelectChannelEndPoint endpoint)
312 {
313 return new HttpConnection(SelectChannelConnector.this,endpoint,getServer())
314 {
315
316 public void cancelTimeout(Task task)
317 {
318 endpoint.getSelectSet().cancelTimeout(task);
319 }
320
321
322 public void scheduleTimeout(Task task, long timeoutMs)
323 {
324 endpoint.getSelectSet().scheduleTimeout(task,timeoutMs);
325 }
326 };
327 }
328 }