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