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