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