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