Mercurial Hosting > luan
annotate src/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @ 948:f5aefdc4a81a
simplify SelectChannelConnector
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 11 Oct 2016 22:16:29 -0600 |
parents | 64f3d8dae31d |
children | e9088af3787f |
rev | line source |
---|---|
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
1 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
2 // ======================================================================== |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
4 // ------------------------------------------------------------------------ |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
5 // All rights reserved. This program and the accompanying materials |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
6 // are made available under the terms of the Eclipse Public License v1.0 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
7 // and Apache License v2.0 which accompanies this distribution. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
8 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
9 // The Eclipse Public License is available at |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
10 // http://www.eclipse.org/legal/epl-v10.html |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
11 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
12 // The Apache License v2.0 is available at |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
13 // http://www.opensource.org/licenses/apache2.0.php |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
14 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
15 // You may elect to redistribute this code under either of these licenses. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
16 // ======================================================================== |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
17 // |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
18 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
19 package org.eclipse.jetty.io.nio; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
20 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
21 import java.io.IOException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
22 import java.io.InterruptedIOException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
23 import java.nio.channels.ClosedChannelException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
24 import java.nio.channels.SelectableChannel; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
25 import java.nio.channels.SelectionKey; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
26 import java.nio.channels.SocketChannel; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
27 import java.util.Locale; |
865 | 28 import java.util.concurrent.RejectedExecutionException; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
29 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
30 import org.eclipse.jetty.io.AsyncEndPoint; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
31 import org.eclipse.jetty.io.Buffer; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
32 import org.eclipse.jetty.io.ConnectedEndPoint; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
33 import org.eclipse.jetty.io.Connection; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
34 import org.eclipse.jetty.io.EofException; |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
35 import org.eclipse.jetty.io.nio.SelectorManager.SelectSet; |
820
8e9db0bbf4f9
remove org.eclipse.jetty.util.log and upgrade slf4j
Franklin Schmidt <fschmidt@gmail.com>
parents:
802
diff
changeset
|
36 import org.slf4j.Logger; |
8e9db0bbf4f9
remove org.eclipse.jetty.util.log and upgrade slf4j
Franklin Schmidt <fschmidt@gmail.com>
parents:
802
diff
changeset
|
37 import org.slf4j.LoggerFactory; |
940
b77d631b9e28
remove scheduleTimeout() and cancelTimeout()
Franklin Schmidt <fschmidt@gmail.com>
parents:
915
diff
changeset
|
38 |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
39 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
40 /* ------------------------------------------------------------ */ |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
41 /** |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
42 * An Endpoint that can be scheduled by {@link SelectorManager}. |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
43 */ |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
44 public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPoint, ConnectedEndPoint |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
45 { |
865 | 46 public static final Logger LOG=LoggerFactory.getLogger("org.eclipse.jetty.io.nio"); |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
47 |
865 | 48 private final SelectorManager.SelectSet _selectSet; |
49 private final SelectorManager _manager; | |
50 private SelectionKey _key; | |
51 private final Runnable _handler = new Runnable() | |
52 { | |
53 public void run() { handle(); } | |
54 }; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
55 |
865 | 56 /** The desired value for {@link SelectionKey#interestOps()} */ |
57 private int _interestOps; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
58 |
865 | 59 /** |
60 * The connection instance is the handler for any IO activity on the endpoint. | |
61 * There is a different type of connection for HTTP, AJP, WebSocket and | |
62 * ProxyConnect. The connection may change for an SCEP as it is upgraded | |
63 * from HTTP to proxy connect or websocket. | |
64 */ | |
65 private volatile AsyncConnection _connection; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
66 |
865 | 67 private static final int STATE_NEEDS_DISPATCH=-1; |
68 private static final int STATE_UNDISPATCHED=0; | |
69 private static final int STATE_DISPATCHED=1; | |
70 private int _state; | |
71 | |
72 private boolean _onIdle; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
73 |
865 | 74 /** true if the last write operation succeed and wrote all offered bytes */ |
75 private volatile boolean _writable = true; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
76 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
77 |
865 | 78 /** True if a thread has is blocked in {@link #blockReadable(long)} */ |
79 private boolean _readBlocked; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
80 |
865 | 81 /** True if a thread has is blocked in {@link #blockWritable(long)} */ |
82 private boolean _writeBlocked; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
83 |
865 | 84 /** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */ |
85 private boolean _open; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
86 |
865 | 87 private volatile long _idleTimestamp; |
88 private volatile boolean _checkIdle; | |
89 | |
90 private boolean _ishut; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
91 |
865 | 92 /* ------------------------------------------------------------ */ |
93 public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key, int maxIdleTime) | |
94 throws IOException | |
95 { | |
96 super(channel, maxIdleTime); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
97 |
865 | 98 _manager = selectSet.getManager(); |
99 _selectSet = selectSet; | |
100 _state=STATE_UNDISPATCHED; | |
101 _onIdle=false; | |
102 _open=true; | |
103 _key = key; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
104 |
865 | 105 setCheckForIdle(true); |
106 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
107 |
865 | 108 /* ------------------------------------------------------------ */ |
109 public SelectionKey getSelectionKey() | |
110 { | |
111 synchronized (this) | |
112 { | |
113 return _key; | |
114 } | |
115 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
116 |
865 | 117 public SelectorManager getSelectManager() |
118 { | |
119 return _manager; | |
120 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
121 |
865 | 122 public Connection getConnection() |
123 { | |
124 return _connection; | |
125 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
126 |
865 | 127 public void setConnection(Connection connection) |
128 { | |
129 _connection=(AsyncConnection)connection; | |
130 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
131 |
865 | 132 /* ------------------------------------------------------------ */ |
133 /** Called by selectSet to schedule handling | |
134 * | |
135 */ | |
136 public void schedule() | |
137 { | |
138 synchronized (this) | |
139 { | |
140 // If there is no key, then do nothing | |
141 if (_key == null || !_key.isValid()) | |
142 { | |
143 _readBlocked=false; | |
144 _writeBlocked=false; | |
145 this.notifyAll(); | |
146 return; | |
147 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
148 |
865 | 149 // If there are threads dispatched reading and writing |
150 if (_readBlocked || _writeBlocked) | |
151 { | |
152 // assert _dispatched; | |
153 if (_readBlocked && _key.isReadable()) | |
154 _readBlocked=false; | |
155 if (_writeBlocked && _key.isWritable()) | |
156 _writeBlocked=false; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
157 |
865 | 158 // wake them up is as good as a dispatched. |
159 this.notifyAll(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
160 |
865 | 161 // we are not interested in further selecting |
162 _key.interestOps(0); | |
163 if (_state<STATE_DISPATCHED) | |
164 updateKey(); | |
165 return; | |
166 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
167 |
865 | 168 // Remove writeable op |
169 if ((_key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) | |
170 { | |
171 // Remove writeable op | |
172 _interestOps = _key.interestOps() & ~SelectionKey.OP_WRITE; | |
173 _key.interestOps(_interestOps); | |
174 _writable = true; // Once writable is in ops, only removed with dispatch. | |
175 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
176 |
865 | 177 // If dispatched, then deregister interest |
178 if (_state>=STATE_DISPATCHED) | |
179 _key.interestOps(0); | |
180 else | |
181 { | |
182 // other wise do the dispatch | |
183 dispatch(); | |
184 } | |
185 } | |
186 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
187 |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
188 public synchronized void dispatch() |
865 | 189 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
190 if (_state<=STATE_UNDISPATCHED) |
865 | 191 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
192 if (_onIdle) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
193 _state = STATE_NEEDS_DISPATCH; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
194 else |
865 | 195 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
196 _state = STATE_DISPATCHED; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
197 try { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
198 _manager.execute(_handler); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
199 } catch(RejectedExecutionException e) { |
865 | 200 _state = STATE_NEEDS_DISPATCH; |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
201 LOG.warn("Dispatched Failed! "+this+" to "+_manager); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
202 updateKey(); |
865 | 203 } |
204 } | |
205 } | |
206 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
207 |
865 | 208 /* ------------------------------------------------------------ */ |
209 /** | |
210 * Called when a dispatched thread is no longer handling the endpoint. | |
211 * The selection key operations are updated. | |
212 * @return If false is returned, the endpoint has been redispatched and | |
213 * thread must keep handling the endpoint. | |
214 */ | |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
215 protected synchronized void undispatch() |
865 | 216 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
217 _state = STATE_UNDISPATCHED; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
218 updateKey(); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
219 // return true; |
865 | 220 } |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
221 |
865 | 222 public void setCheckForIdle(boolean check) |
223 { | |
224 if (check) | |
225 { | |
226 _idleTimestamp=System.currentTimeMillis(); | |
227 _checkIdle=true; | |
228 } | |
229 else | |
230 _checkIdle=false; | |
231 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
232 |
865 | 233 public boolean isCheckForIdle() |
234 { | |
235 return _checkIdle; | |
236 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
237 |
865 | 238 protected void notIdle() |
239 { | |
240 _idleTimestamp=System.currentTimeMillis(); | |
241 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
242 |
865 | 243 public void checkIdleTimestamp(long now) |
244 { | |
245 if (isCheckForIdle() && _maxIdleTime>0) | |
246 { | |
247 final long idleForMs=now-_idleTimestamp; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
248 |
865 | 249 if (idleForMs>_maxIdleTime) |
250 { | |
251 // Don't idle out again until onIdleExpired task completes. | |
252 setCheckForIdle(false); | |
253 _manager.execute(new Runnable() | |
254 { | |
255 public void run() | |
256 { | |
257 try | |
258 { | |
259 onIdleExpired(idleForMs); | |
260 } | |
261 finally | |
262 { | |
263 setCheckForIdle(true); | |
264 } | |
265 } | |
266 }); | |
267 } | |
268 } | |
269 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
270 |
865 | 271 public void onIdleExpired(long idleForMs) |
272 { | |
273 try | |
274 { | |
275 synchronized (this) | |
276 { | |
277 _onIdle=true; | |
278 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
279 |
865 | 280 _connection.onIdleExpired(idleForMs); |
281 } | |
282 finally | |
283 { | |
284 synchronized (this) | |
285 { | |
286 _onIdle=false; | |
287 if (_state==STATE_NEEDS_DISPATCH) | |
288 dispatch(); | |
289 } | |
290 } | |
291 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
292 |
865 | 293 @Override |
294 public int fill(Buffer buffer) throws IOException | |
295 { | |
296 int fill=super.fill(buffer); | |
297 if (fill>0) | |
298 notIdle(); | |
299 return fill; | |
300 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
301 |
865 | 302 @Override |
303 public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException | |
304 { | |
305 int l = super.flush(header, buffer, trailer); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
306 |
865 | 307 // If there was something to write and it wasn't written, then we are not writable. |
308 if (l==0 && ( header!=null && header.hasContent() || buffer!=null && buffer.hasContent() || trailer!=null && trailer.hasContent())) | |
309 { | |
310 synchronized (this) | |
311 { | |
312 _writable=false; | |
313 if (_state<STATE_DISPATCHED) | |
314 updateKey(); | |
315 } | |
316 } | |
317 else if (l>0) | |
318 { | |
319 _writable=true; | |
320 notIdle(); | |
321 } | |
322 return l; | |
323 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
324 |
865 | 325 @Override |
326 public int flush(Buffer buffer) throws IOException | |
327 { | |
328 int l = super.flush(buffer); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
329 |
865 | 330 // If there was something to write and it wasn't written, then we are not writable. |
331 if (l==0 && buffer!=null && buffer.hasContent()) | |
332 { | |
333 synchronized (this) | |
334 { | |
335 _writable=false; | |
336 if (_state<STATE_DISPATCHED) | |
337 updateKey(); | |
338 } | |
339 } | |
340 else if (l>0) | |
341 { | |
342 _writable=true; | |
343 notIdle(); | |
344 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
345 |
865 | 346 return l; |
347 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
348 |
865 | 349 /* ------------------------------------------------------------ */ |
350 /* | |
351 * Allows thread to block waiting for further events. | |
352 */ | |
353 @Override | |
354 public boolean blockReadable(long timeoutMs) throws IOException | |
355 { | |
356 synchronized (this) | |
357 { | |
358 if (isInputShutdown()) | |
359 throw new EofException(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
360 |
865 | 361 long now=_selectSet.getNow(); |
362 long end=now+timeoutMs; | |
363 boolean check=isCheckForIdle(); | |
364 setCheckForIdle(true); | |
365 try | |
366 { | |
367 _readBlocked=true; | |
368 while (!isInputShutdown() && _readBlocked) | |
369 { | |
370 try | |
371 { | |
372 updateKey(); | |
373 this.wait(timeoutMs>0?(end-now):10000); | |
374 } | |
375 catch (final InterruptedException e) | |
376 { | |
377 LOG.warn("",e); | |
378 } | |
379 finally | |
380 { | |
381 now=_selectSet.getNow(); | |
382 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
383 |
865 | 384 if (_readBlocked && timeoutMs>0 && now>=end) |
385 return false; | |
386 } | |
387 } | |
388 finally | |
389 { | |
390 _readBlocked=false; | |
391 setCheckForIdle(check); | |
392 } | |
393 } | |
394 return true; | |
395 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
396 |
865 | 397 /* ------------------------------------------------------------ */ |
398 /* | |
399 * Allows thread to block waiting for further events. | |
400 */ | |
401 @Override | |
402 public boolean blockWritable(long timeoutMs) throws IOException | |
403 { | |
404 synchronized (this) | |
405 { | |
406 if (isOutputShutdown()) | |
407 throw new EofException(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
408 |
865 | 409 long now=_selectSet.getNow(); |
410 long end=now+timeoutMs; | |
411 boolean check=isCheckForIdle(); | |
412 setCheckForIdle(true); | |
413 try | |
414 { | |
415 _writeBlocked=true; | |
416 while (_writeBlocked && !isOutputShutdown()) | |
417 { | |
418 try | |
419 { | |
420 updateKey(); | |
421 this.wait(timeoutMs>0?(end-now):10000); | |
422 } | |
423 catch (final InterruptedException e) | |
424 { | |
425 LOG.warn("",e); | |
426 } | |
427 finally | |
428 { | |
429 now=_selectSet.getNow(); | |
430 } | |
431 if (_writeBlocked && timeoutMs>0 && now>=end) | |
432 return false; | |
433 } | |
434 } | |
435 finally | |
436 { | |
437 _writeBlocked=false; | |
438 setCheckForIdle(check); | |
439 } | |
440 } | |
441 return true; | |
442 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
443 |
865 | 444 /* ------------------------------------------------------------ */ |
445 /** | |
446 * @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite() | |
447 */ | |
448 public void scheduleWrite() | |
449 { | |
450 if (_writable) | |
451 LOG.debug("Required scheduleWrite {}",this); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
452 |
865 | 453 _writable=false; |
454 updateKey(); | |
455 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
456 |
865 | 457 /* ------------------------------------------------------------ */ |
458 public boolean isWritable() | |
459 { | |
460 return _writable; | |
461 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
462 |
865 | 463 /* ------------------------------------------------------------ */ |
464 public boolean hasProgressed() | |
465 { | |
466 return false; | |
467 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
468 |
865 | 469 /* ------------------------------------------------------------ */ |
470 /** | |
471 * Updates selection key. Adds operations types to the selection key as needed. No operations | |
472 * are removed as this is only done during dispatch. This method records the new key and | |
473 * schedules a call to doUpdateKey to do the keyChange | |
474 */ | |
475 private void updateKey() | |
476 { | |
477 final boolean changed; | |
478 synchronized (this) | |
479 { | |
480 int current_ops=-1; | |
481 if (getChannel().isOpen()) | |
482 { | |
483 boolean read_interest = _readBlocked || (_state<STATE_DISPATCHED && !_connection.isSuspended()); | |
484 boolean write_interest= _writeBlocked || (_state<STATE_DISPATCHED && !_writable); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
485 |
865 | 486 _interestOps = |
487 ((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ : 0) | |
488 | ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0); | |
489 try | |
490 { | |
491 current_ops = ((_key!=null && _key.isValid())?_key.interestOps():-1); | |
492 } | |
493 catch(Exception e) | |
494 { | |
495 _key=null; | |
496 LOG.trace("",e); | |
497 } | |
498 } | |
499 changed=_interestOps!=current_ops; | |
500 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
501 |
865 | 502 if(changed) |
503 { | |
504 _selectSet.addChange(this); | |
505 _selectSet.wakeup(); | |
506 } | |
507 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
508 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
509 |
865 | 510 /* ------------------------------------------------------------ */ |
511 /** | |
512 * Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey | |
513 */ | |
514 void doUpdateKey() | |
515 { | |
516 synchronized (this) | |
517 { | |
518 if (getChannel().isOpen()) | |
519 { | |
520 if (_interestOps>0) | |
521 { | |
522 if (_key==null || !_key.isValid()) | |
523 { | |
524 SelectableChannel sc = (SelectableChannel)getChannel(); | |
525 if (sc.isRegistered()) | |
526 { | |
527 updateKey(); | |
528 } | |
529 else | |
530 { | |
531 try | |
532 { | |
533 _key=((SelectableChannel)getChannel()).register(_selectSet.getSelector(),_interestOps,this); | |
534 } | |
535 catch (Exception e) | |
536 { | |
537 LOG.trace("",e); | |
538 if (_key!=null && _key.isValid()) | |
539 { | |
540 _key.cancel(); | |
541 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
542 |
865 | 543 if (_open) |
544 { | |
545 _selectSet.destroyEndPoint(this); | |
546 } | |
547 _open=false; | |
548 _key = null; | |
549 } | |
550 } | |
551 } | |
552 else | |
553 { | |
554 _key.interestOps(_interestOps); | |
555 } | |
556 } | |
557 else | |
558 { | |
559 if (_key!=null && _key.isValid()) | |
560 _key.interestOps(0); | |
561 else | |
562 _key=null; | |
563 } | |
564 } | |
565 else | |
566 { | |
567 if (_key!=null && _key.isValid()) | |
568 _key.cancel(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
569 |
865 | 570 if (_open) |
571 { | |
572 _open=false; | |
573 _selectSet.destroyEndPoint(this); | |
574 } | |
575 _key = null; | |
576 } | |
577 } | |
578 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
579 |
865 | 580 /* ------------------------------------------------------------ */ |
581 /* | |
582 */ | |
583 protected void handle() | |
584 { | |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
585 boolean dispatched = true; |
865 | 586 try |
587 { | |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
588 try |
865 | 589 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
590 while(true) |
865 | 591 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
592 final AsyncConnection next = (AsyncConnection)_connection.handle(); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
593 if (next!=_connection) |
865 | 594 { |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
595 LOG.debug("{} replaced {}",next,_connection); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
596 _connection=next; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
597 continue; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
598 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
599 break; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
600 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
601 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
602 catch (ClosedChannelException e) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
603 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
604 LOG.trace("",e); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
605 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
606 catch (EofException e) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
607 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
608 LOG.debug("EOF", e); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
609 try{close();} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
610 catch(IOException e2){LOG.trace("",e2);} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
611 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
612 catch (IOException e) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
613 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
614 LOG.warn(e.toString()); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
615 try{close();} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
616 catch(IOException e2){LOG.trace("",e2);} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
617 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
618 catch (Throwable e) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
619 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
620 LOG.warn("handle failed", e); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
621 try{close();} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
622 catch(IOException e2){LOG.trace("",e2);} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
623 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
624 finally |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
625 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
626 if (!_ishut && isInputShutdown() && isOpen()) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
627 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
628 _ishut = true; |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
629 try |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
630 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
631 _connection.onInputShutdown(); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
632 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
633 catch(Throwable x) |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
634 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
635 LOG.warn("onInputShutdown failed", x); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
636 try{close();} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
637 catch(IOException e2){LOG.trace("",e2);} |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
638 } |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
639 finally |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
640 { |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
641 updateKey(); |
865 | 642 } |
643 } | |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
644 undispatch(); |
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
645 dispatched = false; |
865 | 646 } |
647 } | |
648 finally | |
649 { | |
650 if (dispatched) | |
651 { | |
947
64f3d8dae31d
simplify SelectChannelEndPoint
Franklin Schmidt <fschmidt@gmail.com>
parents:
946
diff
changeset
|
652 undispatch(); |
865 | 653 } |
654 } | |
655 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
656 |
865 | 657 /* ------------------------------------------------------------ */ |
658 /* | |
659 * @see org.eclipse.io.nio.ChannelEndPoint#close() | |
660 */ | |
661 @Override | |
662 public void close() throws IOException | |
663 { | |
664 try | |
665 { | |
666 super.close(); | |
667 } | |
668 catch (IOException e) | |
669 { | |
670 LOG.trace("",e); | |
671 } | |
672 finally | |
673 { | |
674 updateKey(); | |
675 } | |
676 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
677 |
865 | 678 /* ------------------------------------------------------------ */ |
679 @Override | |
680 public String toString() | |
681 { | |
682 // Do NOT use synchronized (this) | |
683 // because it's very easy to deadlock when debugging is enabled. | |
684 // We do a best effort to print the right toString() and that's it. | |
685 SelectionKey key = _key; | |
686 String keyString = ""; | |
687 if (key != null) | |
688 { | |
689 if (key.isValid()) | |
690 { | |
691 if (key.isReadable()) | |
692 keyString += "r"; | |
693 if (key.isWritable()) | |
694 keyString += "w"; | |
695 } | |
696 else | |
697 { | |
698 keyString += "!"; | |
699 } | |
700 } | |
701 else | |
702 { | |
703 keyString += "-"; | |
704 } | |
705 return String.format("SCEP@%x{l(%s)<->r(%s),s=%d,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s}-{%s}", | |
706 hashCode(), | |
707 _socket.getRemoteSocketAddress(), | |
708 _socket.getLocalSocketAddress(), | |
709 _state, | |
710 isOpen(), | |
711 isInputShutdown(), | |
712 isOutputShutdown(), | |
713 _readBlocked, | |
714 _writeBlocked, | |
715 _writable, | |
716 _interestOps, | |
717 keyString, | |
718 _connection); | |
719 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
720 |
865 | 721 /* ------------------------------------------------------------ */ |
722 /** | |
723 * Don't set the SoTimeout | |
724 * @see org.eclipse.jetty.io.nio.ChannelEndPoint#setMaxIdleTime(int) | |
725 */ | |
726 @Override | |
727 public void setMaxIdleTime(int timeMs) throws IOException | |
728 { | |
729 _maxIdleTime=timeMs; | |
730 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
731 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
732 } |