Mercurial Hosting > luan
annotate src/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java @ 945:89fe80dfab2c
remove asyncDispatch()
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 11 Oct 2016 20:53:06 -0600 |
parents | b77d631b9e28 |
children | 901dcfa05c32 |
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 static final int STATE_ASYNC=2; | |
71 private int _state; | |
72 | |
73 private boolean _onIdle; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
74 |
865 | 75 /** true if the last write operation succeed and wrote all offered bytes */ |
76 private volatile boolean _writable = true; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
77 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
78 |
865 | 79 /** True if a thread has is blocked in {@link #blockReadable(long)} */ |
80 private boolean _readBlocked; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
81 |
865 | 82 /** True if a thread has is blocked in {@link #blockWritable(long)} */ |
83 private boolean _writeBlocked; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
84 |
865 | 85 /** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */ |
86 private boolean _open; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
87 |
865 | 88 private volatile long _idleTimestamp; |
89 private volatile boolean _checkIdle; | |
90 | |
91 private boolean _interruptable; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
92 |
865 | 93 private boolean _ishut; |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
94 |
865 | 95 /* ------------------------------------------------------------ */ |
96 public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key, int maxIdleTime) | |
97 throws IOException | |
98 { | |
99 super(channel, maxIdleTime); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
100 |
865 | 101 _manager = selectSet.getManager(); |
102 _selectSet = selectSet; | |
103 _state=STATE_UNDISPATCHED; | |
104 _onIdle=false; | |
105 _open=true; | |
106 _key = key; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
107 |
865 | 108 setCheckForIdle(true); |
109 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
110 |
865 | 111 /* ------------------------------------------------------------ */ |
112 public SelectionKey getSelectionKey() | |
113 { | |
114 synchronized (this) | |
115 { | |
116 return _key; | |
117 } | |
118 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
119 |
865 | 120 public SelectorManager getSelectManager() |
121 { | |
122 return _manager; | |
123 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
124 |
865 | 125 public Connection getConnection() |
126 { | |
127 return _connection; | |
128 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
129 |
865 | 130 public void setConnection(Connection connection) |
131 { | |
132 _connection=(AsyncConnection)connection; | |
133 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
134 |
865 | 135 /* ------------------------------------------------------------ */ |
136 /** Called by selectSet to schedule handling | |
137 * | |
138 */ | |
139 public void schedule() | |
140 { | |
141 synchronized (this) | |
142 { | |
143 // If there is no key, then do nothing | |
144 if (_key == null || !_key.isValid()) | |
145 { | |
146 _readBlocked=false; | |
147 _writeBlocked=false; | |
148 this.notifyAll(); | |
149 return; | |
150 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
151 |
865 | 152 // If there are threads dispatched reading and writing |
153 if (_readBlocked || _writeBlocked) | |
154 { | |
155 // assert _dispatched; | |
156 if (_readBlocked && _key.isReadable()) | |
157 _readBlocked=false; | |
158 if (_writeBlocked && _key.isWritable()) | |
159 _writeBlocked=false; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
160 |
865 | 161 // wake them up is as good as a dispatched. |
162 this.notifyAll(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
163 |
865 | 164 // we are not interested in further selecting |
165 _key.interestOps(0); | |
166 if (_state<STATE_DISPATCHED) | |
167 updateKey(); | |
168 return; | |
169 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
170 |
865 | 171 // Remove writeable op |
172 if ((_key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) | |
173 { | |
174 // Remove writeable op | |
175 _interestOps = _key.interestOps() & ~SelectionKey.OP_WRITE; | |
176 _key.interestOps(_interestOps); | |
177 _writable = true; // Once writable is in ops, only removed with dispatch. | |
178 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
179 |
865 | 180 // If dispatched, then deregister interest |
181 if (_state>=STATE_DISPATCHED) | |
182 _key.interestOps(0); | |
183 else | |
184 { | |
185 // other wise do the dispatch | |
186 dispatch(); | |
187 } | |
188 } | |
189 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
190 |
865 | 191 /* ------------------------------------------------------------ */ |
192 public void dispatch() | |
193 { | |
194 synchronized(this) | |
195 { | |
196 if (_state<=STATE_UNDISPATCHED) | |
197 { | |
198 if (_onIdle) | |
199 _state = STATE_NEEDS_DISPATCH; | |
200 else | |
201 { | |
202 _state = STATE_DISPATCHED; | |
203 try { | |
204 _manager.execute(_handler); | |
205 } catch(RejectedExecutionException e) { | |
206 _state = STATE_NEEDS_DISPATCH; | |
207 LOG.warn("Dispatched Failed! "+this+" to "+_manager); | |
208 updateKey(); | |
209 } | |
210 } | |
211 } | |
212 } | |
213 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
214 |
865 | 215 /* ------------------------------------------------------------ */ |
216 /** | |
217 * Called when a dispatched thread is no longer handling the endpoint. | |
218 * The selection key operations are updated. | |
219 * @return If false is returned, the endpoint has been redispatched and | |
220 * thread must keep handling the endpoint. | |
221 */ | |
222 protected boolean undispatch() | |
223 { | |
224 synchronized (this) | |
225 { | |
226 switch(_state) | |
227 { | |
228 case STATE_ASYNC: | |
229 _state=STATE_DISPATCHED; | |
230 return false; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
231 |
865 | 232 default: |
233 _state=STATE_UNDISPATCHED; | |
234 updateKey(); | |
235 return true; | |
236 } | |
237 } | |
238 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
239 |
865 | 240 /* ------------------------------------------------------------ */ |
241 public void setCheckForIdle(boolean check) | |
242 { | |
243 if (check) | |
244 { | |
245 _idleTimestamp=System.currentTimeMillis(); | |
246 _checkIdle=true; | |
247 } | |
248 else | |
249 _checkIdle=false; | |
250 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
251 |
865 | 252 /* ------------------------------------------------------------ */ |
253 public boolean isCheckForIdle() | |
254 { | |
255 return _checkIdle; | |
256 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
257 |
865 | 258 /* ------------------------------------------------------------ */ |
259 protected void notIdle() | |
260 { | |
261 _idleTimestamp=System.currentTimeMillis(); | |
262 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
263 |
865 | 264 /* ------------------------------------------------------------ */ |
265 public void checkIdleTimestamp(long now) | |
266 { | |
267 if (isCheckForIdle() && _maxIdleTime>0) | |
268 { | |
269 final long idleForMs=now-_idleTimestamp; | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
270 |
865 | 271 if (idleForMs>_maxIdleTime) |
272 { | |
273 // Don't idle out again until onIdleExpired task completes. | |
274 setCheckForIdle(false); | |
275 _manager.execute(new Runnable() | |
276 { | |
277 public void run() | |
278 { | |
279 try | |
280 { | |
281 onIdleExpired(idleForMs); | |
282 } | |
283 finally | |
284 { | |
285 setCheckForIdle(true); | |
286 } | |
287 } | |
288 }); | |
289 } | |
290 } | |
291 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
292 |
865 | 293 /* ------------------------------------------------------------ */ |
294 public void onIdleExpired(long idleForMs) | |
295 { | |
296 try | |
297 { | |
298 synchronized (this) | |
299 { | |
300 _onIdle=true; | |
301 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
302 |
865 | 303 _connection.onIdleExpired(idleForMs); |
304 } | |
305 finally | |
306 { | |
307 synchronized (this) | |
308 { | |
309 _onIdle=false; | |
310 if (_state==STATE_NEEDS_DISPATCH) | |
311 dispatch(); | |
312 } | |
313 } | |
314 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
315 |
865 | 316 /* ------------------------------------------------------------ */ |
317 @Override | |
318 public int fill(Buffer buffer) throws IOException | |
319 { | |
320 int fill=super.fill(buffer); | |
321 if (fill>0) | |
322 notIdle(); | |
323 return fill; | |
324 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
325 |
865 | 326 /* ------------------------------------------------------------ */ |
327 @Override | |
328 public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException | |
329 { | |
330 int l = super.flush(header, buffer, trailer); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
331 |
865 | 332 // If there was something to write and it wasn't written, then we are not writable. |
333 if (l==0 && ( header!=null && header.hasContent() || buffer!=null && buffer.hasContent() || trailer!=null && trailer.hasContent())) | |
334 { | |
335 synchronized (this) | |
336 { | |
337 _writable=false; | |
338 if (_state<STATE_DISPATCHED) | |
339 updateKey(); | |
340 } | |
341 } | |
342 else if (l>0) | |
343 { | |
344 _writable=true; | |
345 notIdle(); | |
346 } | |
347 return l; | |
348 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
349 |
865 | 350 /* ------------------------------------------------------------ */ |
351 /* | |
352 */ | |
353 @Override | |
354 public int flush(Buffer buffer) throws IOException | |
355 { | |
356 int l = super.flush(buffer); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
357 |
865 | 358 // If there was something to write and it wasn't written, then we are not writable. |
359 if (l==0 && buffer!=null && buffer.hasContent()) | |
360 { | |
361 synchronized (this) | |
362 { | |
363 _writable=false; | |
364 if (_state<STATE_DISPATCHED) | |
365 updateKey(); | |
366 } | |
367 } | |
368 else if (l>0) | |
369 { | |
370 _writable=true; | |
371 notIdle(); | |
372 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
373 |
865 | 374 return l; |
375 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
376 |
865 | 377 /* ------------------------------------------------------------ */ |
378 /* | |
379 * Allows thread to block waiting for further events. | |
380 */ | |
381 @Override | |
382 public boolean blockReadable(long timeoutMs) throws IOException | |
383 { | |
384 synchronized (this) | |
385 { | |
386 if (isInputShutdown()) | |
387 throw new EofException(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
388 |
865 | 389 long now=_selectSet.getNow(); |
390 long end=now+timeoutMs; | |
391 boolean check=isCheckForIdle(); | |
392 setCheckForIdle(true); | |
393 try | |
394 { | |
395 _readBlocked=true; | |
396 while (!isInputShutdown() && _readBlocked) | |
397 { | |
398 try | |
399 { | |
400 updateKey(); | |
401 this.wait(timeoutMs>0?(end-now):10000); | |
402 } | |
403 catch (final InterruptedException e) | |
404 { | |
405 LOG.warn("",e); | |
406 if (_interruptable) | |
407 throw new InterruptedIOException(){{this.initCause(e);}}; | |
408 } | |
409 finally | |
410 { | |
411 now=_selectSet.getNow(); | |
412 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
413 |
865 | 414 if (_readBlocked && timeoutMs>0 && now>=end) |
415 return false; | |
416 } | |
417 } | |
418 finally | |
419 { | |
420 _readBlocked=false; | |
421 setCheckForIdle(check); | |
422 } | |
423 } | |
424 return true; | |
425 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
426 |
865 | 427 /* ------------------------------------------------------------ */ |
428 /* | |
429 * Allows thread to block waiting for further events. | |
430 */ | |
431 @Override | |
432 public boolean blockWritable(long timeoutMs) throws IOException | |
433 { | |
434 synchronized (this) | |
435 { | |
436 if (isOutputShutdown()) | |
437 throw new EofException(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
438 |
865 | 439 long now=_selectSet.getNow(); |
440 long end=now+timeoutMs; | |
441 boolean check=isCheckForIdle(); | |
442 setCheckForIdle(true); | |
443 try | |
444 { | |
445 _writeBlocked=true; | |
446 while (_writeBlocked && !isOutputShutdown()) | |
447 { | |
448 try | |
449 { | |
450 updateKey(); | |
451 this.wait(timeoutMs>0?(end-now):10000); | |
452 } | |
453 catch (final InterruptedException e) | |
454 { | |
455 LOG.warn("",e); | |
456 if (_interruptable) | |
457 throw new InterruptedIOException(){{this.initCause(e);}}; | |
458 } | |
459 finally | |
460 { | |
461 now=_selectSet.getNow(); | |
462 } | |
463 if (_writeBlocked && timeoutMs>0 && now>=end) | |
464 return false; | |
465 } | |
466 } | |
467 finally | |
468 { | |
469 _writeBlocked=false; | |
470 setCheckForIdle(check); | |
471 } | |
472 } | |
473 return true; | |
474 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
475 |
865 | 476 /* ------------------------------------------------------------ */ |
477 /** Set the interruptable mode of the endpoint. | |
478 * If set to false (default), then interrupts are assumed to be spurious | |
479 * and blocking operations continue unless the endpoint has been closed. | |
480 * If true, then interrupts of blocking operations result in InterruptedIOExceptions | |
481 * being thrown. | |
482 * @param interupable | |
483 */ | |
484 public void setInterruptable(boolean interupable) | |
485 { | |
486 synchronized (this) | |
487 { | |
488 _interruptable=interupable; | |
489 } | |
490 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
491 |
865 | 492 /* ------------------------------------------------------------ */ |
493 public boolean isInterruptable() | |
494 { | |
495 return _interruptable; | |
496 } | |
497 | |
498 /* ------------------------------------------------------------ */ | |
499 /** | |
500 * @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite() | |
501 */ | |
502 public void scheduleWrite() | |
503 { | |
504 if (_writable) | |
505 LOG.debug("Required scheduleWrite {}",this); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
506 |
865 | 507 _writable=false; |
508 updateKey(); | |
509 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
510 |
865 | 511 /* ------------------------------------------------------------ */ |
512 public boolean isWritable() | |
513 { | |
514 return _writable; | |
515 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
516 |
865 | 517 /* ------------------------------------------------------------ */ |
518 public boolean hasProgressed() | |
519 { | |
520 return false; | |
521 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
522 |
865 | 523 /* ------------------------------------------------------------ */ |
524 /** | |
525 * Updates selection key. Adds operations types to the selection key as needed. No operations | |
526 * are removed as this is only done during dispatch. This method records the new key and | |
527 * schedules a call to doUpdateKey to do the keyChange | |
528 */ | |
529 private void updateKey() | |
530 { | |
531 final boolean changed; | |
532 synchronized (this) | |
533 { | |
534 int current_ops=-1; | |
535 if (getChannel().isOpen()) | |
536 { | |
537 boolean read_interest = _readBlocked || (_state<STATE_DISPATCHED && !_connection.isSuspended()); | |
538 boolean write_interest= _writeBlocked || (_state<STATE_DISPATCHED && !_writable); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
539 |
865 | 540 _interestOps = |
541 ((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ : 0) | |
542 | ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0); | |
543 try | |
544 { | |
545 current_ops = ((_key!=null && _key.isValid())?_key.interestOps():-1); | |
546 } | |
547 catch(Exception e) | |
548 { | |
549 _key=null; | |
550 LOG.trace("",e); | |
551 } | |
552 } | |
553 changed=_interestOps!=current_ops; | |
554 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
555 |
865 | 556 if(changed) |
557 { | |
558 _selectSet.addChange(this); | |
559 _selectSet.wakeup(); | |
560 } | |
561 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
562 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
563 |
865 | 564 /* ------------------------------------------------------------ */ |
565 /** | |
566 * Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey | |
567 */ | |
568 void doUpdateKey() | |
569 { | |
570 synchronized (this) | |
571 { | |
572 if (getChannel().isOpen()) | |
573 { | |
574 if (_interestOps>0) | |
575 { | |
576 if (_key==null || !_key.isValid()) | |
577 { | |
578 SelectableChannel sc = (SelectableChannel)getChannel(); | |
579 if (sc.isRegistered()) | |
580 { | |
581 updateKey(); | |
582 } | |
583 else | |
584 { | |
585 try | |
586 { | |
587 _key=((SelectableChannel)getChannel()).register(_selectSet.getSelector(),_interestOps,this); | |
588 } | |
589 catch (Exception e) | |
590 { | |
591 LOG.trace("",e); | |
592 if (_key!=null && _key.isValid()) | |
593 { | |
594 _key.cancel(); | |
595 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
596 |
865 | 597 if (_open) |
598 { | |
599 _selectSet.destroyEndPoint(this); | |
600 } | |
601 _open=false; | |
602 _key = null; | |
603 } | |
604 } | |
605 } | |
606 else | |
607 { | |
608 _key.interestOps(_interestOps); | |
609 } | |
610 } | |
611 else | |
612 { | |
613 if (_key!=null && _key.isValid()) | |
614 _key.interestOps(0); | |
615 else | |
616 _key=null; | |
617 } | |
618 } | |
619 else | |
620 { | |
621 if (_key!=null && _key.isValid()) | |
622 _key.cancel(); | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
623 |
865 | 624 if (_open) |
625 { | |
626 _open=false; | |
627 _selectSet.destroyEndPoint(this); | |
628 } | |
629 _key = null; | |
630 } | |
631 } | |
632 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
633 |
865 | 634 /* ------------------------------------------------------------ */ |
635 /* | |
636 */ | |
637 protected void handle() | |
638 { | |
639 boolean dispatched=true; | |
640 try | |
641 { | |
642 while(dispatched) | |
643 { | |
644 try | |
645 { | |
646 while(true) | |
647 { | |
648 final AsyncConnection next = (AsyncConnection)_connection.handle(); | |
649 if (next!=_connection) | |
650 { | |
651 LOG.debug("{} replaced {}",next,_connection); | |
652 _connection=next; | |
653 continue; | |
654 } | |
655 break; | |
656 } | |
657 } | |
658 catch (ClosedChannelException e) | |
659 { | |
660 LOG.trace("",e); | |
661 } | |
662 catch (EofException e) | |
663 { | |
664 LOG.debug("EOF", e); | |
665 try{close();} | |
666 catch(IOException e2){LOG.trace("",e2);} | |
667 } | |
668 catch (IOException e) | |
669 { | |
670 LOG.warn(e.toString()); | |
671 try{close();} | |
672 catch(IOException e2){LOG.trace("",e2);} | |
673 } | |
674 catch (Throwable e) | |
675 { | |
676 LOG.warn("handle failed", e); | |
677 try{close();} | |
678 catch(IOException e2){LOG.trace("",e2);} | |
679 } | |
680 finally | |
681 { | |
682 if (!_ishut && isInputShutdown() && isOpen()) | |
683 { | |
684 _ishut=true; | |
685 try | |
686 { | |
687 _connection.onInputShutdown(); | |
688 } | |
689 catch(Throwable x) | |
690 { | |
691 LOG.warn("onInputShutdown failed", x); | |
692 try{close();} | |
693 catch(IOException e2){LOG.trace("",e2);} | |
694 } | |
695 finally | |
696 { | |
697 updateKey(); | |
698 } | |
699 } | |
700 dispatched=!undispatch(); | |
701 } | |
702 } | |
703 } | |
704 finally | |
705 { | |
706 if (dispatched) | |
707 { | |
708 dispatched=!undispatch(); | |
709 while (dispatched) | |
710 { | |
711 LOG.warn("SCEP.run() finally DISPATCHED"); | |
712 dispatched=!undispatch(); | |
713 } | |
714 } | |
715 } | |
716 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
717 |
865 | 718 /* ------------------------------------------------------------ */ |
719 /* | |
720 * @see org.eclipse.io.nio.ChannelEndPoint#close() | |
721 */ | |
722 @Override | |
723 public void close() throws IOException | |
724 { | |
725 try | |
726 { | |
727 super.close(); | |
728 } | |
729 catch (IOException e) | |
730 { | |
731 LOG.trace("",e); | |
732 } | |
733 finally | |
734 { | |
735 updateKey(); | |
736 } | |
737 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
738 |
865 | 739 /* ------------------------------------------------------------ */ |
740 @Override | |
741 public String toString() | |
742 { | |
743 // Do NOT use synchronized (this) | |
744 // because it's very easy to deadlock when debugging is enabled. | |
745 // We do a best effort to print the right toString() and that's it. | |
746 SelectionKey key = _key; | |
747 String keyString = ""; | |
748 if (key != null) | |
749 { | |
750 if (key.isValid()) | |
751 { | |
752 if (key.isReadable()) | |
753 keyString += "r"; | |
754 if (key.isWritable()) | |
755 keyString += "w"; | |
756 } | |
757 else | |
758 { | |
759 keyString += "!"; | |
760 } | |
761 } | |
762 else | |
763 { | |
764 keyString += "-"; | |
765 } | |
766 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}", | |
767 hashCode(), | |
768 _socket.getRemoteSocketAddress(), | |
769 _socket.getLocalSocketAddress(), | |
770 _state, | |
771 isOpen(), | |
772 isInputShutdown(), | |
773 isOutputShutdown(), | |
774 _readBlocked, | |
775 _writeBlocked, | |
776 _writable, | |
777 _interestOps, | |
778 keyString, | |
779 _connection); | |
780 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
781 |
865 | 782 /* ------------------------------------------------------------ */ |
783 public SelectSet getSelectSet() | |
784 { | |
785 return _selectSet; | |
786 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
787 |
865 | 788 /* ------------------------------------------------------------ */ |
789 /** | |
790 * Don't set the SoTimeout | |
791 * @see org.eclipse.jetty.io.nio.ChannelEndPoint#setMaxIdleTime(int) | |
792 */ | |
793 @Override | |
794 public void setMaxIdleTime(int timeMs) throws IOException | |
795 { | |
796 _maxIdleTime=timeMs; | |
797 } | |
802
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
798 |
3428c60d7cfc
replace jetty jars with source
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff
changeset
|
799 } |