Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/AsyncContinuation.java @ 865:6b210bb66c63
remove ThreadPool
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 02 Oct 2016 20:38:06 -0600 |
parents | 8e9db0bbf4f9 |
children | b9aa175d9a29 |
comparison
equal
deleted
inserted
replaced
864:e21ca9878a10 | 865:6b210bb66c63 |
---|---|
48 /** Implementation of Continuation and AsyncContext interfaces | 48 /** Implementation of Continuation and AsyncContext interfaces |
49 * | 49 * |
50 */ | 50 */ |
51 public class AsyncContinuation implements AsyncContext, Continuation | 51 public class AsyncContinuation implements AsyncContext, Continuation |
52 { | 52 { |
53 private static final Logger LOG = LoggerFactory.getLogger(AsyncContinuation.class); | 53 private static final Logger LOG = LoggerFactory.getLogger(AsyncContinuation.class); |
54 | 54 |
55 private final static long DEFAULT_TIMEOUT=30000L; | 55 private final static long DEFAULT_TIMEOUT=30000L; |
56 | 56 |
57 private final static ContinuationThrowable __exception = new ContinuationThrowable(); | 57 private final static ContinuationThrowable __exception = new ContinuationThrowable(); |
58 | 58 |
59 // STATES: | 59 // STATES: |
60 // handling() suspend() unhandle() resume() complete() doComplete() | 60 // handling() suspend() unhandle() resume() complete() doComplete() |
61 // startAsync() dispatch() | 61 // startAsync() dispatch() |
62 // IDLE DISPATCHED | 62 // IDLE DISPATCHED |
63 // DISPATCHED ASYNCSTARTED UNCOMPLETED | 63 // DISPATCHED ASYNCSTARTED UNCOMPLETED |
64 // ASYNCSTARTED ASYNCWAIT REDISPATCHING COMPLETING | 64 // ASYNCSTARTED ASYNCWAIT REDISPATCHING COMPLETING |
65 // REDISPATCHING REDISPATCHED | 65 // REDISPATCHING REDISPATCHED |
66 // ASYNCWAIT REDISPATCH COMPLETING | 66 // ASYNCWAIT REDISPATCH COMPLETING |
67 // REDISPATCH REDISPATCHED | 67 // REDISPATCH REDISPATCHED |
68 // REDISPATCHED ASYNCSTARTED UNCOMPLETED | 68 // REDISPATCHED ASYNCSTARTED UNCOMPLETED |
69 // COMPLETING UNCOMPLETED UNCOMPLETED | 69 // COMPLETING UNCOMPLETED UNCOMPLETED |
70 // UNCOMPLETED COMPLETED | 70 // UNCOMPLETED COMPLETED |
71 // COMPLETED | 71 // COMPLETED |
72 private static final int __IDLE=0; // Idle request | 72 private static final int __IDLE=0; // Idle request |
73 private static final int __DISPATCHED=1; // Request dispatched to filter/servlet | 73 private static final int __DISPATCHED=1; // Request dispatched to filter/servlet |
74 private static final int __ASYNCSTARTED=2; // Suspend called, but not yet returned to container | 74 private static final int __ASYNCSTARTED=2; // Suspend called, but not yet returned to container |
75 private static final int __REDISPATCHING=3;// resumed while dispatched | 75 private static final int __REDISPATCHING=3;// resumed while dispatched |
76 private static final int __ASYNCWAIT=4; // Suspended and parked | 76 private static final int __ASYNCWAIT=4; // Suspended and parked |
77 private static final int __REDISPATCH=5; // Has been scheduled | 77 private static final int __REDISPATCH=5; // Has been scheduled |
78 private static final int __REDISPATCHED=6; // Request redispatched to filter/servlet | 78 private static final int __REDISPATCHED=6; // Request redispatched to filter/servlet |
79 private static final int __COMPLETING=7; // complete while dispatched | 79 private static final int __COMPLETING=7; // complete while dispatched |
80 private static final int __UNCOMPLETED=8; // Request is completable | 80 private static final int __UNCOMPLETED=8; // Request is completable |
81 private static final int __COMPLETED=9; // Request is complete | 81 private static final int __COMPLETED=9; // Request is complete |
82 | 82 |
83 /* ------------------------------------------------------------ */ | 83 /* ------------------------------------------------------------ */ |
84 protected AbstractHttpConnection _connection; | 84 protected AbstractHttpConnection _connection; |
85 private List<AsyncListener> _lastAsyncListeners; | 85 private List<AsyncListener> _lastAsyncListeners; |
86 private List<AsyncListener> _asyncListeners; | 86 private List<AsyncListener> _asyncListeners; |
87 private List<ContinuationListener> _continuationListeners; | 87 private List<ContinuationListener> _continuationListeners; |
88 | 88 |
89 /* ------------------------------------------------------------ */ | 89 /* ------------------------------------------------------------ */ |
90 private int _state; | 90 private int _state; |
91 private boolean _initial; | 91 private boolean _initial; |
92 private boolean _resumed; | 92 private boolean _resumed; |
93 private boolean _expired; | 93 private boolean _expired; |
94 private volatile boolean _responseWrapped; | 94 private volatile boolean _responseWrapped; |
95 private long _timeoutMs=DEFAULT_TIMEOUT; | 95 private long _timeoutMs=DEFAULT_TIMEOUT; |
96 private AsyncEventState _event; | 96 private AsyncEventState _event; |
97 private volatile long _expireAt; | 97 private volatile long _expireAt; |
98 private volatile boolean _continuation; | 98 private volatile boolean _continuation; |
99 | 99 |
100 /* ------------------------------------------------------------ */ | 100 /* ------------------------------------------------------------ */ |
101 protected AsyncContinuation() | 101 protected AsyncContinuation() |
102 { | 102 { |
103 _state=__IDLE; | 103 _state=__IDLE; |
104 _initial=true; | 104 _initial=true; |
105 } | 105 } |
106 | 106 |
107 /* ------------------------------------------------------------ */ | 107 /* ------------------------------------------------------------ */ |
108 protected void setConnection(final AbstractHttpConnection connection) | 108 protected void setConnection(final AbstractHttpConnection connection) |
109 { | 109 { |
110 synchronized(this) | 110 synchronized(this) |
111 { | 111 { |
112 _connection=connection; | 112 _connection=connection; |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 /* ------------------------------------------------------------ */ | 116 /* ------------------------------------------------------------ */ |
117 public void addListener(AsyncListener listener) | 117 public void addListener(AsyncListener listener) |
118 { | 118 { |
119 synchronized(this) | 119 synchronized(this) |
120 { | 120 { |
121 if (_asyncListeners==null) | 121 if (_asyncListeners==null) |
122 _asyncListeners=new ArrayList<AsyncListener>(); | 122 _asyncListeners=new ArrayList<AsyncListener>(); |
123 _asyncListeners.add(listener); | 123 _asyncListeners.add(listener); |
124 } | 124 } |
125 } | 125 } |
126 | 126 |
127 /* ------------------------------------------------------------ */ | 127 /* ------------------------------------------------------------ */ |
128 public void addListener(AsyncListener listener,ServletRequest request, ServletResponse response) | 128 public void addListener(AsyncListener listener,ServletRequest request, ServletResponse response) |
129 { | 129 { |
130 synchronized(this) | 130 synchronized(this) |
131 { | 131 { |
132 // TODO handle the request/response ??? | 132 // TODO handle the request/response ??? |
133 if (_asyncListeners==null) | 133 if (_asyncListeners==null) |
134 _asyncListeners=new ArrayList<AsyncListener>(); | 134 _asyncListeners=new ArrayList<AsyncListener>(); |
135 _asyncListeners.add(listener); | 135 _asyncListeners.add(listener); |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 /* ------------------------------------------------------------ */ | 139 /* ------------------------------------------------------------ */ |
140 public void addContinuationListener(ContinuationListener listener) | 140 public void addContinuationListener(ContinuationListener listener) |
141 { | 141 { |
142 synchronized(this) | 142 synchronized(this) |
143 { | 143 { |
144 if (_continuationListeners==null) | 144 if (_continuationListeners==null) |
145 _continuationListeners=new ArrayList<ContinuationListener>(); | 145 _continuationListeners=new ArrayList<ContinuationListener>(); |
146 _continuationListeners.add(listener); | 146 _continuationListeners.add(listener); |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 /* ------------------------------------------------------------ */ | 150 /* ------------------------------------------------------------ */ |
151 public void setTimeout(long ms) | 151 public void setTimeout(long ms) |
152 { | 152 { |
153 synchronized(this) | 153 synchronized(this) |
154 { | 154 { |
155 _timeoutMs=ms; | 155 _timeoutMs=ms; |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 /* ------------------------------------------------------------ */ | 159 /* ------------------------------------------------------------ */ |
160 public long getTimeout() | 160 public long getTimeout() |
161 { | 161 { |
162 synchronized(this) | 162 synchronized(this) |
163 { | 163 { |
164 return _timeoutMs; | 164 return _timeoutMs; |
165 } | 165 } |
166 } | 166 } |
167 | 167 |
168 /* ------------------------------------------------------------ */ | 168 /* ------------------------------------------------------------ */ |
169 public AsyncEventState getAsyncEventState() | 169 public AsyncEventState getAsyncEventState() |
170 { | 170 { |
171 synchronized(this) | 171 synchronized(this) |
172 { | 172 { |
173 return _event; | 173 return _event; |
174 } | 174 } |
175 } | 175 } |
176 | 176 |
177 /* ------------------------------------------------------------ */ | 177 /* ------------------------------------------------------------ */ |
178 /** | 178 /** |
179 * @see org.eclipse.jetty.continuation.Continuation#keepWrappers() | 179 * @see org.eclipse.jetty.continuation.Continuation#keepWrappers() |
180 */ | 180 */ |
181 | 181 |
182 /* ------------------------------------------------------------ */ | 182 /* ------------------------------------------------------------ */ |
183 /** | 183 /** |
184 * @see org.eclipse.jetty.continuation.Continuation#isResponseWrapped() | 184 * @see org.eclipse.jetty.continuation.Continuation#isResponseWrapped() |
185 */ | 185 */ |
186 public boolean isResponseWrapped() | 186 public boolean isResponseWrapped() |
187 { | 187 { |
188 return _responseWrapped; | 188 return _responseWrapped; |
189 } | 189 } |
190 | 190 |
191 /* ------------------------------------------------------------ */ | 191 /* ------------------------------------------------------------ */ |
192 /* (non-Javadoc) | 192 /* (non-Javadoc) |
193 * @see javax.servlet.ServletRequest#isInitial() | 193 * @see javax.servlet.ServletRequest#isInitial() |
194 */ | 194 */ |
195 public boolean isInitial() | 195 public boolean isInitial() |
196 { | 196 { |
197 synchronized(this) | 197 synchronized(this) |
198 { | 198 { |
199 return _initial; | 199 return _initial; |
200 } | 200 } |
201 } | 201 } |
202 | 202 |
203 public boolean isContinuation() | 203 public boolean isContinuation() |
204 { | 204 { |
205 return _continuation; | 205 return _continuation; |
206 } | 206 } |
207 | 207 |
208 /* ------------------------------------------------------------ */ | 208 /* ------------------------------------------------------------ */ |
209 /* (non-Javadoc) | 209 /* (non-Javadoc) |
210 * @see javax.servlet.ServletRequest#isSuspended() | 210 * @see javax.servlet.ServletRequest#isSuspended() |
211 */ | 211 */ |
212 public boolean isSuspended() | 212 public boolean isSuspended() |
213 { | 213 { |
214 synchronized(this) | 214 synchronized(this) |
215 { | 215 { |
216 switch(_state) | 216 switch(_state) |
217 { | 217 { |
218 case __ASYNCSTARTED: | 218 case __ASYNCSTARTED: |
219 case __REDISPATCHING: | 219 case __REDISPATCHING: |
220 case __COMPLETING: | 220 case __COMPLETING: |
221 case __ASYNCWAIT: | 221 case __ASYNCWAIT: |
222 return true; | 222 return true; |
223 | 223 |
224 default: | 224 default: |
225 return false; | 225 return false; |
226 } | 226 } |
227 } | 227 } |
228 } | 228 } |
229 | 229 |
230 /* ------------------------------------------------------------ */ | 230 /* ------------------------------------------------------------ */ |
231 public boolean isSuspending() | 231 public boolean isSuspending() |
232 { | 232 { |
233 synchronized(this) | 233 synchronized(this) |
234 { | 234 { |
235 switch(_state) | 235 switch(_state) |
236 { | 236 { |
237 case __ASYNCSTARTED: | 237 case __ASYNCSTARTED: |
238 case __ASYNCWAIT: | 238 case __ASYNCWAIT: |
239 return true; | 239 return true; |
240 | 240 |
241 default: | 241 default: |
242 return false; | 242 return false; |
243 } | 243 } |
244 } | 244 } |
245 } | 245 } |
246 | 246 |
247 /* ------------------------------------------------------------ */ | 247 /* ------------------------------------------------------------ */ |
248 public boolean isDispatchable() | 248 public boolean isDispatchable() |
249 { | 249 { |
250 synchronized(this) | 250 synchronized(this) |
251 { | 251 { |
252 switch(_state) | 252 switch(_state) |
253 { | 253 { |
254 case __REDISPATCH: | 254 case __REDISPATCH: |
255 case __REDISPATCHED: | 255 case __REDISPATCHED: |
256 case __REDISPATCHING: | 256 case __REDISPATCHING: |
257 case __COMPLETING: | 257 case __COMPLETING: |
258 return true; | 258 return true; |
259 | 259 |
260 default: | 260 default: |
261 return false; | 261 return false; |
262 } | 262 } |
263 } | 263 } |
264 } | 264 } |
265 | 265 |
266 /* ------------------------------------------------------------ */ | 266 /* ------------------------------------------------------------ */ |
267 @Override | 267 @Override |
268 public String toString() | 268 public String toString() |
269 { | 269 { |
270 synchronized (this) | 270 synchronized (this) |
271 { | 271 { |
272 return super.toString()+"@"+getStatusString(); | 272 return super.toString()+"@"+getStatusString(); |
273 } | 273 } |
274 } | 274 } |
275 | 275 |
276 /* ------------------------------------------------------------ */ | 276 /* ------------------------------------------------------------ */ |
277 public String getStatusString() | 277 public String getStatusString() |
278 { | 278 { |
279 synchronized (this) | 279 synchronized (this) |
280 { | 280 { |
281 return | 281 return |
282 ((_state==__IDLE)?"IDLE": | 282 ((_state==__IDLE)?"IDLE": |
283 (_state==__DISPATCHED)?"DISPATCHED": | 283 (_state==__DISPATCHED)?"DISPATCHED": |
284 (_state==__ASYNCSTARTED)?"ASYNCSTARTED": | 284 (_state==__ASYNCSTARTED)?"ASYNCSTARTED": |
285 (_state==__ASYNCWAIT)?"ASYNCWAIT": | 285 (_state==__ASYNCWAIT)?"ASYNCWAIT": |
286 (_state==__REDISPATCHING)?"REDISPATCHING": | 286 (_state==__REDISPATCHING)?"REDISPATCHING": |
287 (_state==__REDISPATCH)?"REDISPATCH": | 287 (_state==__REDISPATCH)?"REDISPATCH": |
288 (_state==__REDISPATCHED)?"REDISPATCHED": | 288 (_state==__REDISPATCHED)?"REDISPATCHED": |
289 (_state==__COMPLETING)?"COMPLETING": | 289 (_state==__COMPLETING)?"COMPLETING": |
290 (_state==__UNCOMPLETED)?"UNCOMPLETED": | 290 (_state==__UNCOMPLETED)?"UNCOMPLETED": |
291 (_state==__COMPLETED)?"COMPLETE": | 291 (_state==__COMPLETED)?"COMPLETE": |
292 ("UNKNOWN?"+_state))+ | 292 ("UNKNOWN?"+_state))+ |
293 (_initial?",initial":"")+ | 293 (_initial?",initial":"")+ |
294 (_resumed?",resumed":"")+ | 294 (_resumed?",resumed":"")+ |
295 (_expired?",expired":""); | 295 (_expired?",expired":""); |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 /* ------------------------------------------------------------ */ | 299 /* ------------------------------------------------------------ */ |
300 /** | 300 /** |
301 * @return false if the handling of the request should not proceed | 301 * @return false if the handling of the request should not proceed |
302 */ | 302 */ |
303 protected boolean handling() | 303 protected boolean handling() |
304 { | 304 { |
305 synchronized (this) | 305 synchronized (this) |
306 { | 306 { |
307 _continuation=false; | 307 _continuation=false; |
308 | 308 |
309 switch(_state) | 309 switch(_state) |
310 { | 310 { |
311 case __IDLE: | 311 case __IDLE: |
312 _initial=true; | 312 _initial=true; |
313 _state=__DISPATCHED; | 313 _state=__DISPATCHED; |
314 if (_lastAsyncListeners!=null) | 314 if (_lastAsyncListeners!=null) |
315 _lastAsyncListeners.clear(); | 315 _lastAsyncListeners.clear(); |
316 if (_asyncListeners!=null) | 316 if (_asyncListeners!=null) |
317 _asyncListeners.clear(); | 317 _asyncListeners.clear(); |
318 else | 318 else |
319 { | 319 { |
320 _asyncListeners=_lastAsyncListeners; | 320 _asyncListeners=_lastAsyncListeners; |
321 _lastAsyncListeners=null; | 321 _lastAsyncListeners=null; |
322 } | 322 } |
323 return true; | 323 return true; |
324 | 324 |
325 case __COMPLETING: | 325 case __COMPLETING: |
326 _state=__UNCOMPLETED; | 326 _state=__UNCOMPLETED; |
327 return false; | 327 return false; |
328 | 328 |
329 case __ASYNCWAIT: | 329 case __ASYNCWAIT: |
330 return false; | 330 return false; |
331 | 331 |
332 case __REDISPATCH: | 332 case __REDISPATCH: |
333 _state=__REDISPATCHED; | 333 _state=__REDISPATCHED; |
334 return true; | 334 return true; |
335 | 335 |
336 default: | 336 default: |
337 throw new IllegalStateException(this.getStatusString()); | 337 throw new IllegalStateException(this.getStatusString()); |
338 } | 338 } |
339 } | 339 } |
340 } | 340 } |
341 | 341 |
342 /* ------------------------------------------------------------ */ | 342 /* ------------------------------------------------------------ */ |
343 /* (non-Javadoc) | 343 /* (non-Javadoc) |
344 * @see javax.servlet.ServletRequest#suspend(long) | 344 * @see javax.servlet.ServletRequest#suspend(long) |
345 */ | 345 */ |
346 private void doSuspend(final ServletContext context, | 346 private void doSuspend(final ServletContext context, |
347 final ServletRequest request, | 347 final ServletRequest request, |
348 final ServletResponse response) | 348 final ServletResponse response) |
349 { | 349 { |
350 synchronized (this) | 350 synchronized (this) |
351 { | 351 { |
352 switch(_state) | 352 switch(_state) |
353 { | 353 { |
354 case __DISPATCHED: | 354 case __DISPATCHED: |
355 case __REDISPATCHED: | 355 case __REDISPATCHED: |
356 _resumed=false; | 356 _resumed=false; |
357 _expired=false; | 357 _expired=false; |
358 | 358 |
359 if (_event==null || request!=_event.getSuppliedRequest() || response != _event.getSuppliedResponse() || context != _event.getServletContext()) | 359 if (_event==null || request!=_event.getSuppliedRequest() || response != _event.getSuppliedResponse() || context != _event.getServletContext()) |
360 _event=new AsyncEventState(context,request,response); | 360 _event=new AsyncEventState(context,request,response); |
361 else | 361 else |
362 { | 362 { |
363 _event._dispatchContext=null; | 363 _event._dispatchContext=null; |
364 _event._pathInContext=null; | 364 _event._pathInContext=null; |
365 } | 365 } |
366 _state=__ASYNCSTARTED; | 366 _state=__ASYNCSTARTED; |
367 List<AsyncListener> recycle=_lastAsyncListeners; | 367 List<AsyncListener> recycle=_lastAsyncListeners; |
368 _lastAsyncListeners=_asyncListeners; | 368 _lastAsyncListeners=_asyncListeners; |
369 _asyncListeners=recycle; | 369 _asyncListeners=recycle; |
370 if (_asyncListeners!=null) | 370 if (_asyncListeners!=null) |
371 _asyncListeners.clear(); | 371 _asyncListeners.clear(); |
372 break; | 372 break; |
373 | 373 |
374 default: | 374 default: |
375 throw new IllegalStateException(this.getStatusString()); | 375 throw new IllegalStateException(this.getStatusString()); |
376 } | 376 } |
377 } | 377 } |
378 | 378 |
379 if (_lastAsyncListeners!=null) | 379 if (_lastAsyncListeners!=null) |
380 { | 380 { |
381 for (AsyncListener listener : _lastAsyncListeners) | 381 for (AsyncListener listener : _lastAsyncListeners) |
382 { | 382 { |
383 try | 383 try |
384 { | 384 { |
385 listener.onStartAsync(_event); | 385 listener.onStartAsync(_event); |
386 } | 386 } |
387 catch(Exception e) | 387 catch(Exception e) |
388 { | 388 { |
389 LOG.warn("",e); | 389 LOG.warn("",e); |
390 } | 390 } |
391 } | 391 } |
392 } | 392 } |
393 } | 393 } |
394 | 394 |
395 /* ------------------------------------------------------------ */ | 395 /* ------------------------------------------------------------ */ |
396 /** | 396 /** |
397 * Signal that the HttpConnection has finished handling the request. | 397 * Signal that the HttpConnection has finished handling the request. |
398 * For blocking connectors, this call may block if the request has | 398 * For blocking connectors, this call may block if the request has |
399 * been suspended (startAsync called). | 399 * been suspended (startAsync called). |
400 * @return true if handling is complete, false if the request should | 400 * @return true if handling is complete, false if the request should |
401 * be handled again (eg because of a resume that happened before unhandle was called) | 401 * be handled again (eg because of a resume that happened before unhandle was called) |
402 */ | 402 */ |
403 protected boolean unhandle() | 403 protected boolean unhandle() |
404 { | 404 { |
405 synchronized (this) | 405 synchronized (this) |
406 { | 406 { |
407 switch(_state) | 407 switch(_state) |
408 { | 408 { |
409 case __REDISPATCHED: | 409 case __REDISPATCHED: |
410 case __DISPATCHED: | 410 case __DISPATCHED: |
411 _state=__UNCOMPLETED; | 411 _state=__UNCOMPLETED; |
412 return true; | 412 return true; |
413 | 413 |
414 case __IDLE: | 414 case __IDLE: |
415 throw new IllegalStateException(this.getStatusString()); | 415 throw new IllegalStateException(this.getStatusString()); |
416 | 416 |
417 case __ASYNCSTARTED: | 417 case __ASYNCSTARTED: |
418 _initial=false; | 418 _initial=false; |
419 _state=__ASYNCWAIT; | 419 _state=__ASYNCWAIT; |
420 scheduleTimeout(); // could block and change state. | 420 scheduleTimeout(); // could block and change state. |
421 if (_state==__ASYNCWAIT) | 421 if (_state==__ASYNCWAIT) |
422 return true; | 422 return true; |
423 else if (_state==__COMPLETING) | 423 else if (_state==__COMPLETING) |
424 { | 424 { |
425 _state=__UNCOMPLETED; | 425 _state=__UNCOMPLETED; |
426 return true; | 426 return true; |
427 } | 427 } |
428 _initial=false; | 428 _initial=false; |
429 _state=__REDISPATCHED; | 429 _state=__REDISPATCHED; |
430 return false; | 430 return false; |
431 | 431 |
432 case __REDISPATCHING: | 432 case __REDISPATCHING: |
433 _initial=false; | 433 _initial=false; |
434 _state=__REDISPATCHED; | 434 _state=__REDISPATCHED; |
435 return false; | 435 return false; |
436 | 436 |
437 case __COMPLETING: | 437 case __COMPLETING: |
438 _initial=false; | 438 _initial=false; |
439 _state=__UNCOMPLETED; | 439 _state=__UNCOMPLETED; |
440 return true; | 440 return true; |
441 | 441 |
442 default: | 442 default: |
443 throw new IllegalStateException(this.getStatusString()); | 443 throw new IllegalStateException(this.getStatusString()); |
444 } | 444 } |
445 } | 445 } |
446 } | 446 } |
447 | 447 |
448 /* ------------------------------------------------------------ */ | 448 /* ------------------------------------------------------------ */ |
449 public void dispatch() | 449 public void dispatch() |
450 { | 450 { |
451 boolean dispatch=false; | 451 boolean dispatch=false; |
452 synchronized (this) | 452 synchronized (this) |
453 { | 453 { |
454 switch(_state) | 454 switch(_state) |
455 { | 455 { |
456 case __ASYNCSTARTED: | 456 case __ASYNCSTARTED: |
457 _state=__REDISPATCHING; | 457 _state=__REDISPATCHING; |
458 _resumed=true; | 458 _resumed=true; |
459 return; | 459 return; |
460 | 460 |
461 case __ASYNCWAIT: | 461 case __ASYNCWAIT: |
462 dispatch=!_expired; | 462 dispatch=!_expired; |
463 _state=__REDISPATCH; | 463 _state=__REDISPATCH; |
464 _resumed=true; | 464 _resumed=true; |
465 break; | 465 break; |
466 | 466 |
467 case __REDISPATCH: | 467 case __REDISPATCH: |
468 return; | 468 return; |
469 | 469 |
470 default: | 470 default: |
471 throw new IllegalStateException(this.getStatusString()); | 471 throw new IllegalStateException(this.getStatusString()); |
472 } | 472 } |
473 } | 473 } |
474 | 474 |
475 if (dispatch) | 475 if (dispatch) |
476 { | 476 { |
477 cancelTimeout(); | 477 cancelTimeout(); |
478 scheduleDispatch(); | 478 scheduleDispatch(); |
479 } | 479 } |
480 } | 480 } |
481 | 481 |
482 /* ------------------------------------------------------------ */ | 482 /* ------------------------------------------------------------ */ |
483 protected void expired() | 483 protected void expired() |
484 { | 484 { |
485 final List<ContinuationListener> cListeners; | 485 final List<ContinuationListener> cListeners; |
486 final List<AsyncListener> aListeners; | 486 final List<AsyncListener> aListeners; |
487 synchronized (this) | 487 synchronized (this) |
488 { | 488 { |
489 switch(_state) | 489 switch(_state) |
490 { | 490 { |
491 case __ASYNCSTARTED: | 491 case __ASYNCSTARTED: |
492 case __ASYNCWAIT: | 492 case __ASYNCWAIT: |
493 cListeners=_continuationListeners; | 493 cListeners=_continuationListeners; |
494 aListeners=_asyncListeners; | 494 aListeners=_asyncListeners; |
495 break; | 495 break; |
496 default: | 496 default: |
497 cListeners=null; | 497 cListeners=null; |
498 aListeners=null; | 498 aListeners=null; |
499 return; | 499 return; |
500 } | 500 } |
501 _expired=true; | 501 _expired=true; |
502 } | 502 } |
503 | 503 |
504 if (aListeners!=null) | 504 if (aListeners!=null) |
505 { | 505 { |
506 for (AsyncListener listener : aListeners) | 506 for (AsyncListener listener : aListeners) |
507 { | 507 { |
508 try | 508 try |
509 { | 509 { |
510 listener.onTimeout(_event); | 510 listener.onTimeout(_event); |
511 } | 511 } |
512 catch(Exception e) | 512 catch(Exception e) |
513 { | 513 { |
514 LOG.debug("",e); | 514 LOG.debug("",e); |
515 _connection.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e); | 515 _connection.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e); |
516 break; | 516 break; |
517 } | 517 } |
518 } | 518 } |
519 } | 519 } |
520 if (cListeners!=null) | 520 if (cListeners!=null) |
521 { | 521 { |
522 for (ContinuationListener listener : cListeners) | 522 for (ContinuationListener listener : cListeners) |
523 { | 523 { |
524 try | 524 try |
525 { | 525 { |
526 listener.onTimeout(this); | 526 listener.onTimeout(this); |
527 } | 527 } |
528 catch(Exception e) | 528 catch(Exception e) |
529 { | 529 { |
530 LOG.warn("",e); | 530 LOG.warn("",e); |
531 } | 531 } |
532 } | 532 } |
533 } | 533 } |
534 | 534 |
535 synchronized (this) | 535 synchronized (this) |
536 { | 536 { |
537 switch(_state) | 537 switch(_state) |
538 { | 538 { |
539 case __ASYNCSTARTED: | 539 case __ASYNCSTARTED: |
540 case __ASYNCWAIT: | 540 case __ASYNCWAIT: |
541 dispatch(); | 541 dispatch(); |
542 break; | 542 break; |
543 | 543 |
544 default: | 544 default: |
545 if (!_continuation) | 545 if (!_continuation) |
546 _expired=false; | 546 _expired=false; |
547 } | 547 } |
548 } | 548 } |
549 | 549 |
550 scheduleDispatch(); | 550 scheduleDispatch(); |
551 } | 551 } |
552 | 552 |
553 /* ------------------------------------------------------------ */ | 553 /* ------------------------------------------------------------ */ |
554 /* (non-Javadoc) | 554 /* (non-Javadoc) |
555 * @see javax.servlet.ServletRequest#complete() | 555 * @see javax.servlet.ServletRequest#complete() |
556 */ | 556 */ |
557 public void complete() | 557 public void complete() |
558 { | 558 { |
559 // just like resume, except don't set _resumed=true; | 559 // just like resume, except don't set _resumed=true; |
560 boolean dispatch=false; | 560 boolean dispatch=false; |
561 synchronized (this) | 561 synchronized (this) |
562 { | 562 { |
563 switch(_state) | 563 switch(_state) |
564 { | 564 { |
565 case __DISPATCHED: | 565 case __DISPATCHED: |
566 case __REDISPATCHED: | 566 case __REDISPATCHED: |
567 throw new IllegalStateException(this.getStatusString()); | 567 throw new IllegalStateException(this.getStatusString()); |
568 | 568 |
569 case __ASYNCSTARTED: | 569 case __ASYNCSTARTED: |
570 _state=__COMPLETING; | 570 _state=__COMPLETING; |
571 return; | 571 return; |
572 | 572 |
573 case __ASYNCWAIT: | 573 case __ASYNCWAIT: |
574 _state=__COMPLETING; | 574 _state=__COMPLETING; |
575 dispatch=!_expired; | 575 dispatch=!_expired; |
576 break; | 576 break; |
577 | 577 |
578 default: | 578 default: |
579 throw new IllegalStateException(this.getStatusString()); | 579 throw new IllegalStateException(this.getStatusString()); |
580 } | 580 } |
581 } | 581 } |
582 | 582 |
583 if (dispatch) | 583 if (dispatch) |
584 { | 584 { |
585 cancelTimeout(); | 585 cancelTimeout(); |
586 scheduleDispatch(); | 586 scheduleDispatch(); |
587 } | 587 } |
588 } | 588 } |
589 | 589 |
590 /* ------------------------------------------------------------ */ | 590 /* ------------------------------------------------------------ */ |
591 /* (non-Javadoc) | 591 /* (non-Javadoc) |
592 * @see javax.servlet.ServletRequest#complete() | 592 * @see javax.servlet.ServletRequest#complete() |
593 */ | 593 */ |
594 public void errorComplete() | 594 public void errorComplete() |
595 { | 595 { |
596 // just like complete except can overrule a prior dispatch call; | 596 // just like complete except can overrule a prior dispatch call; |
597 synchronized (this) | 597 synchronized (this) |
598 { | 598 { |
599 switch(_state) | 599 switch(_state) |
600 { | 600 { |
601 case __REDISPATCHING: | 601 case __REDISPATCHING: |
602 case __ASYNCSTARTED: | 602 case __ASYNCSTARTED: |
603 _state=__COMPLETING; | 603 _state=__COMPLETING; |
604 _resumed=false; | 604 _resumed=false; |
605 return; | 605 return; |
606 | 606 |
607 case __COMPLETING: | 607 case __COMPLETING: |
608 return; | 608 return; |
609 | 609 |
610 default: | 610 default: |
611 throw new IllegalStateException(this.getStatusString()); | 611 throw new IllegalStateException(this.getStatusString()); |
612 } | 612 } |
613 } | 613 } |
614 } | 614 } |
615 | 615 |
616 /* ------------------------------------------------------------ */ | 616 /* ------------------------------------------------------------ */ |
617 @Override | 617 @Override |
618 public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException | 618 public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException |
619 { | 619 { |
620 try | 620 try |
621 { | 621 { |
622 // TODO inject | 622 // TODO inject |
623 return clazz.newInstance(); | 623 return clazz.newInstance(); |
624 } | 624 } |
625 catch(Exception e) | 625 catch(Exception e) |
626 { | 626 { |
627 throw new ServletException(e); | 627 throw new ServletException(e); |
628 } | 628 } |
629 } | 629 } |
630 | 630 |
631 | 631 |
632 /* ------------------------------------------------------------ */ | 632 /* ------------------------------------------------------------ */ |
633 /* (non-Javadoc) | 633 /* (non-Javadoc) |
634 * @see javax.servlet.ServletRequest#complete() | 634 * @see javax.servlet.ServletRequest#complete() |
635 */ | 635 */ |
636 protected void doComplete(Throwable ex) | 636 protected void doComplete(Throwable ex) |
637 { | 637 { |
638 final List<ContinuationListener> cListeners; | 638 final List<ContinuationListener> cListeners; |
639 final List<AsyncListener> aListeners; | 639 final List<AsyncListener> aListeners; |
640 synchronized (this) | 640 synchronized (this) |
641 { | 641 { |
642 switch(_state) | 642 switch(_state) |
643 { | 643 { |
644 case __UNCOMPLETED: | 644 case __UNCOMPLETED: |
645 _state=__COMPLETED; | 645 _state=__COMPLETED; |
646 cListeners=_continuationListeners; | 646 cListeners=_continuationListeners; |
647 aListeners=_asyncListeners; | 647 aListeners=_asyncListeners; |
648 break; | 648 break; |
649 | 649 |
650 default: | 650 default: |
651 cListeners=null; | 651 cListeners=null; |
652 aListeners=null; | 652 aListeners=null; |
653 throw new IllegalStateException(this.getStatusString()); | 653 throw new IllegalStateException(this.getStatusString()); |
654 } | 654 } |
655 } | 655 } |
656 | 656 |
657 if (aListeners!=null) | 657 if (aListeners!=null) |
658 { | 658 { |
659 for (AsyncListener listener : aListeners) | 659 for (AsyncListener listener : aListeners) |
660 { | 660 { |
661 try | 661 try |
662 { | 662 { |
663 if (ex!=null) | 663 if (ex!=null) |
664 { | 664 { |
665 _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,ex); | 665 _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,ex); |
666 _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_MESSAGE,ex.getMessage()); | 666 _event.getSuppliedRequest().setAttribute(RequestDispatcher.ERROR_MESSAGE,ex.getMessage()); |
667 listener.onError(_event); | 667 listener.onError(_event); |
668 } | 668 } |
669 else | 669 else |
670 listener.onComplete(_event); | 670 listener.onComplete(_event); |
671 } | 671 } |
672 catch(Exception e) | 672 catch(Exception e) |
673 { | 673 { |
674 LOG.warn("",e); | 674 LOG.warn("",e); |
675 } | 675 } |
676 } | 676 } |
677 } | 677 } |
678 if (cListeners!=null) | 678 if (cListeners!=null) |
679 { | 679 { |
680 for (ContinuationListener listener : cListeners) | 680 for (ContinuationListener listener : cListeners) |
681 { | 681 { |
682 try | 682 try |
683 { | 683 { |
684 listener.onComplete(this); | 684 listener.onComplete(this); |
685 } | 685 } |
686 catch(Exception e) | 686 catch(Exception e) |
687 { | 687 { |
688 LOG.warn("",e); | 688 LOG.warn("",e); |
689 } | 689 } |
690 } | 690 } |
691 } | 691 } |
692 } | 692 } |
693 | 693 |
694 /* ------------------------------------------------------------ */ | 694 /* ------------------------------------------------------------ */ |
695 protected void recycle() | 695 protected void recycle() |
696 { | 696 { |
697 synchronized (this) | 697 synchronized (this) |
698 { | 698 { |
699 switch(_state) | 699 switch(_state) |
700 { | 700 { |
701 case __DISPATCHED: | 701 case __DISPATCHED: |
702 case __REDISPATCHED: | 702 case __REDISPATCHED: |
703 throw new IllegalStateException(getStatusString()); | 703 throw new IllegalStateException(getStatusString()); |
704 default: | 704 default: |
705 _state=__IDLE; | 705 _state=__IDLE; |
706 } | 706 } |
707 _initial = true; | 707 _initial = true; |
708 _resumed=false; | 708 _resumed=false; |
709 _expired=false; | 709 _expired=false; |
710 _responseWrapped=false; | 710 _responseWrapped=false; |
711 cancelTimeout(); | 711 cancelTimeout(); |
712 _timeoutMs=DEFAULT_TIMEOUT; | 712 _timeoutMs=DEFAULT_TIMEOUT; |
713 _continuationListeners=null; | 713 _continuationListeners=null; |
714 } | 714 } |
715 } | 715 } |
716 | 716 |
717 /* ------------------------------------------------------------ */ | 717 /* ------------------------------------------------------------ */ |
718 public void cancel() | 718 public void cancel() |
719 { | 719 { |
720 synchronized (this) | 720 synchronized (this) |
721 { | 721 { |
722 cancelTimeout(); | 722 cancelTimeout(); |
723 _continuationListeners=null; | 723 _continuationListeners=null; |
724 } | 724 } |
725 } | 725 } |
726 | 726 |
727 /* ------------------------------------------------------------ */ | 727 /* ------------------------------------------------------------ */ |
728 protected void scheduleDispatch() | 728 protected void scheduleDispatch() |
729 { | 729 { |
730 EndPoint endp=_connection.getEndPoint(); | 730 EndPoint endp=_connection.getEndPoint(); |
731 if (!endp.isBlocking()) | 731 if (!endp.isBlocking()) |
732 { | 732 { |
733 ((AsyncEndPoint)endp).asyncDispatch(); | 733 ((AsyncEndPoint)endp).asyncDispatch(); |
734 } | 734 } |
735 } | 735 } |
736 | 736 |
737 /* ------------------------------------------------------------ */ | 737 /* ------------------------------------------------------------ */ |
738 protected void scheduleTimeout() | 738 protected void scheduleTimeout() |
739 { | 739 { |
740 EndPoint endp=_connection.getEndPoint(); | 740 EndPoint endp=_connection.getEndPoint(); |
741 if (_timeoutMs>0) | 741 if (_timeoutMs>0) |
742 { | 742 { |
743 if (endp.isBlocking()) | 743 if (endp.isBlocking()) |
744 { | 744 { |
745 synchronized(this) | 745 synchronized(this) |
746 { | 746 { |
747 _expireAt = System.currentTimeMillis()+_timeoutMs; | 747 _expireAt = System.currentTimeMillis()+_timeoutMs; |
748 long wait=_timeoutMs; | 748 long wait=_timeoutMs; |
749 while (_expireAt>0 && wait>0 && _connection.getServer().isRunning()) | 749 while (_expireAt>0 && wait>0 && _connection.getServer().isRunning()) |
750 { | 750 { |
751 try | 751 try |
752 { | 752 { |
753 this.wait(wait); | 753 this.wait(wait); |
754 } | 754 } |
755 catch (InterruptedException e) | 755 catch (InterruptedException e) |
756 { | 756 { |
757 LOG.trace("",e); | 757 LOG.trace("",e); |
758 } | 758 } |
759 wait=_expireAt-System.currentTimeMillis(); | 759 wait=_expireAt-System.currentTimeMillis(); |
760 } | 760 } |
761 | 761 |
762 if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning()) | 762 if (_expireAt>0 && wait<=0 && _connection.getServer().isRunning()) |
763 { | 763 { |
764 expired(); | 764 expired(); |
765 } | 765 } |
766 } | 766 } |
767 } | 767 } |
768 else | 768 else |
769 { | 769 { |
770 ((AsyncEndPoint)endp).scheduleTimeout(_event._timeout,_timeoutMs); | 770 ((AsyncEndPoint)endp).scheduleTimeout(_event._timeout,_timeoutMs); |
771 } | 771 } |
772 } | 772 } |
773 } | 773 } |
774 | 774 |
775 /* ------------------------------------------------------------ */ | 775 /* ------------------------------------------------------------ */ |
776 protected void cancelTimeout() | 776 protected void cancelTimeout() |
777 { | 777 { |
778 EndPoint endp=_connection.getEndPoint(); | 778 EndPoint endp=_connection.getEndPoint(); |
779 if (endp.isBlocking()) | 779 if (endp.isBlocking()) |
780 { | 780 { |
781 synchronized(this) | 781 synchronized(this) |
782 { | 782 { |
783 _expireAt=0; | 783 _expireAt=0; |
784 this.notifyAll(); | 784 this.notifyAll(); |
785 } | 785 } |
786 } | 786 } |
787 else | 787 else |
788 { | 788 { |
789 final AsyncEventState event=_event; | 789 final AsyncEventState event=_event; |
790 if (event!=null) | 790 if (event!=null) |
791 { | 791 { |
792 ((AsyncEndPoint)endp).cancelTimeout(event._timeout); | 792 ((AsyncEndPoint)endp).cancelTimeout(event._timeout); |
793 } | 793 } |
794 } | 794 } |
795 } | 795 } |
796 | 796 |
797 /* ------------------------------------------------------------ */ | 797 /* ------------------------------------------------------------ */ |
798 public boolean isCompleting() | 798 public boolean isCompleting() |
799 { | 799 { |
800 synchronized (this) | 800 synchronized (this) |
801 { | 801 { |
802 return _state==__COMPLETING; | 802 return _state==__COMPLETING; |
803 } | 803 } |
804 } | 804 } |
805 | 805 |
806 /* ------------------------------------------------------------ */ | 806 /* ------------------------------------------------------------ */ |
807 boolean isUncompleted() | 807 boolean isUncompleted() |
808 { | 808 { |
809 synchronized (this) | 809 synchronized (this) |
810 { | 810 { |
811 return _state==__UNCOMPLETED; | 811 return _state==__UNCOMPLETED; |
812 } | 812 } |
813 } | 813 } |
814 | 814 |
815 /* ------------------------------------------------------------ */ | 815 /* ------------------------------------------------------------ */ |
816 public boolean isComplete() | 816 public boolean isComplete() |
817 { | 817 { |
818 synchronized (this) | 818 synchronized (this) |
819 { | 819 { |
820 return _state==__COMPLETED; | 820 return _state==__COMPLETED; |
821 } | 821 } |
822 } | 822 } |
823 | 823 |
824 | 824 |
825 /* ------------------------------------------------------------ */ | 825 /* ------------------------------------------------------------ */ |
826 public boolean isAsyncStarted() | 826 public boolean isAsyncStarted() |
827 { | 827 { |
828 synchronized (this) | 828 synchronized (this) |
829 { | 829 { |
830 switch(_state) | 830 switch(_state) |
831 { | 831 { |
832 case __ASYNCSTARTED: | 832 case __ASYNCSTARTED: |
833 case __REDISPATCHING: | 833 case __REDISPATCHING: |
834 case __REDISPATCH: | 834 case __REDISPATCH: |
835 case __ASYNCWAIT: | 835 case __ASYNCWAIT: |
836 return true; | 836 return true; |
837 | 837 |
838 default: | 838 default: |
839 return false; | 839 return false; |
840 } | 840 } |
841 } | 841 } |
842 } | 842 } |
843 | 843 |
844 | 844 |
845 /* ------------------------------------------------------------ */ | 845 /* ------------------------------------------------------------ */ |
846 public boolean isAsync() | 846 public boolean isAsync() |
847 { | 847 { |
848 synchronized (this) | 848 synchronized (this) |
849 { | 849 { |
850 switch(_state) | 850 switch(_state) |
851 { | 851 { |
852 case __IDLE: | 852 case __IDLE: |
853 case __DISPATCHED: | 853 case __DISPATCHED: |
854 case __UNCOMPLETED: | 854 case __UNCOMPLETED: |
855 case __COMPLETED: | 855 case __COMPLETED: |
856 return false; | 856 return false; |
857 | 857 |
858 default: | 858 default: |
859 return true; | 859 return true; |
860 } | 860 } |
861 } | 861 } |
862 } | 862 } |
863 | 863 |
864 /* ------------------------------------------------------------ */ | 864 /* ------------------------------------------------------------ */ |
865 public void dispatch(ServletContext context, String path) | 865 public void dispatch(ServletContext context, String path) |
866 { | 866 { |
867 _event._dispatchContext=context; | 867 _event._dispatchContext=context; |
868 _event.setPath(path); | 868 _event.setPath(path); |
869 dispatch(); | 869 dispatch(); |
870 } | 870 } |
871 | 871 |
872 /* ------------------------------------------------------------ */ | 872 /* ------------------------------------------------------------ */ |
873 public void dispatch(String path) | 873 public void dispatch(String path) |
874 { | 874 { |
875 _event.setPath(path); | 875 _event.setPath(path); |
876 dispatch(); | 876 dispatch(); |
877 } | 877 } |
878 | 878 |
879 /* ------------------------------------------------------------ */ | 879 /* ------------------------------------------------------------ */ |
880 public Request getBaseRequest() | 880 public Request getBaseRequest() |
881 { | 881 { |
882 return _connection.getRequest(); | 882 return _connection.getRequest(); |
883 } | 883 } |
884 | 884 |
885 /* ------------------------------------------------------------ */ | 885 /* ------------------------------------------------------------ */ |
886 public ServletRequest getRequest() | 886 public ServletRequest getRequest() |
887 { | 887 { |
888 if (_event!=null) | 888 if (_event!=null) |
889 return _event.getSuppliedRequest(); | 889 return _event.getSuppliedRequest(); |
890 return _connection.getRequest(); | 890 return _connection.getRequest(); |
891 } | 891 } |
892 | 892 |
893 /* ------------------------------------------------------------ */ | 893 /* ------------------------------------------------------------ */ |
894 public ServletResponse getResponse() | 894 public ServletResponse getResponse() |
895 { | 895 { |
896 if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null) | 896 if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null) |
897 return _event.getSuppliedResponse(); | 897 return _event.getSuppliedResponse(); |
898 return _connection.getResponse(); | 898 return _connection.getResponse(); |
899 } | 899 } |
900 | 900 |
901 /* ------------------------------------------------------------ */ | 901 /* ------------------------------------------------------------ */ |
902 public void start(final Runnable run) | 902 public void start(final Runnable run) |
903 { | 903 { |
904 final AsyncEventState event=_event; | 904 final AsyncEventState event=_event; |
905 if (event!=null) | 905 if (event!=null) |
906 { | 906 { |
907 _connection.getServer().getThreadPool().dispatch(new Runnable() | 907 _connection.getServer().getThreadPool().execute(new Runnable() |
908 { | 908 { |
909 public void run() | 909 public void run() |
910 { | 910 { |
911 ((Context)event.getServletContext()).getContextHandler().handle(run); | 911 ((Context)event.getServletContext()).getContextHandler().handle(run); |
912 } | 912 } |
913 }); | 913 }); |
914 } | 914 } |
915 } | 915 } |
916 | 916 |
917 /* ------------------------------------------------------------ */ | 917 /* ------------------------------------------------------------ */ |
918 public boolean hasOriginalRequestAndResponse() | 918 public boolean hasOriginalRequestAndResponse() |
919 { | 919 { |
920 synchronized (this) | 920 synchronized (this) |
921 { | 921 { |
922 return (_event!=null && _event.getSuppliedRequest()==_connection._request && _event.getSuppliedResponse()==_connection._response); | 922 return (_event!=null && _event.getSuppliedRequest()==_connection._request && _event.getSuppliedResponse()==_connection._response); |
923 } | 923 } |
924 } | 924 } |
925 | 925 |
926 /* ------------------------------------------------------------ */ | 926 /* ------------------------------------------------------------ */ |
927 public ContextHandler getContextHandler() | 927 public ContextHandler getContextHandler() |
928 { | 928 { |
929 final AsyncEventState event=_event; | 929 final AsyncEventState event=_event; |
930 if (event!=null) | 930 if (event!=null) |
931 return ((Context)event.getServletContext()).getContextHandler(); | 931 return ((Context)event.getServletContext()).getContextHandler(); |
932 return null; | 932 return null; |
933 } | 933 } |
934 | 934 |
935 | 935 |
936 /* ------------------------------------------------------------ */ | 936 /* ------------------------------------------------------------ */ |
937 /** | 937 /** |
938 * @see Continuation#isResumed() | 938 * @see Continuation#isResumed() |
939 */ | 939 */ |
940 public boolean isResumed() | 940 public boolean isResumed() |
941 { | 941 { |
942 synchronized (this) | 942 synchronized (this) |
943 { | 943 { |
944 return _resumed; | 944 return _resumed; |
945 } | 945 } |
946 } | 946 } |
947 /* ------------------------------------------------------------ */ | 947 /* ------------------------------------------------------------ */ |
948 /** | 948 /** |
949 * @see Continuation#isExpired() | 949 * @see Continuation#isExpired() |
950 */ | 950 */ |
951 public boolean isExpired() | 951 public boolean isExpired() |
952 { | 952 { |
953 synchronized (this) | 953 synchronized (this) |
954 { | 954 { |
955 return _expired; | 955 return _expired; |
956 } | 956 } |
957 } | 957 } |
958 | 958 |
959 /* ------------------------------------------------------------ */ | 959 /* ------------------------------------------------------------ */ |
960 /** | 960 /** |
961 * @see Continuation#resume() | 961 * @see Continuation#resume() |
962 */ | 962 */ |
963 public void resume() | 963 public void resume() |
964 { | 964 { |
965 dispatch(); | 965 dispatch(); |
966 } | 966 } |
967 | 967 |
968 | 968 |
969 | 969 |
970 /* ------------------------------------------------------------ */ | 970 /* ------------------------------------------------------------ */ |
971 protected void startAsync(final ServletContext context, | 971 protected void startAsync(final ServletContext context, |
972 final ServletRequest request, | 972 final ServletRequest request, |
973 final ServletResponse response) | 973 final ServletResponse response) |
974 { | 974 { |
975 synchronized (this) | 975 synchronized (this) |
976 { | 976 { |
977 _responseWrapped=!(response instanceof Response); | 977 _responseWrapped=!(response instanceof Response); |
978 doSuspend(context,request,response); | 978 doSuspend(context,request,response); |
979 if (request instanceof HttpServletRequest) | 979 if (request instanceof HttpServletRequest) |
980 { | 980 { |
981 _event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo()); | 981 _event._pathInContext = URIUtil.addPaths(((HttpServletRequest)request).getServletPath(),((HttpServletRequest)request).getPathInfo()); |
982 } | 982 } |
983 } | 983 } |
984 } | 984 } |
985 | 985 |
986 /* ------------------------------------------------------------ */ | 986 /* ------------------------------------------------------------ */ |
987 protected void startAsync() | 987 protected void startAsync() |
988 { | 988 { |
989 _responseWrapped=false; | 989 _responseWrapped=false; |
990 _continuation=false; | 990 _continuation=false; |
991 doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse()); | 991 doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse()); |
992 } | 992 } |
993 | 993 |
994 | 994 |
995 /* ------------------------------------------------------------ */ | 995 /* ------------------------------------------------------------ */ |
996 /** | 996 /** |
997 * @see Continuation#suspend() | 997 * @see Continuation#suspend() |
998 */ | 998 */ |
999 public void suspend(ServletResponse response) | 999 public void suspend(ServletResponse response) |
1000 { | 1000 { |
1001 _continuation=true; | 1001 _continuation=true; |
1002 _responseWrapped=!(response instanceof Response); | 1002 _responseWrapped=!(response instanceof Response); |
1003 doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),response); | 1003 doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),response); |
1004 } | 1004 } |
1005 | 1005 |
1006 /* ------------------------------------------------------------ */ | 1006 /* ------------------------------------------------------------ */ |
1007 /** | 1007 /** |
1008 * @see Continuation#suspend() | 1008 * @see Continuation#suspend() |
1009 */ | 1009 */ |
1010 public void suspend() | 1010 public void suspend() |
1011 { | 1011 { |
1012 _responseWrapped=false; | 1012 _responseWrapped=false; |
1013 _continuation=true; | 1013 _continuation=true; |
1014 doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse()); | 1014 doSuspend(_connection.getRequest().getServletContext(),_connection.getRequest(),_connection.getResponse()); |
1015 } | 1015 } |
1016 | 1016 |
1017 /* ------------------------------------------------------------ */ | 1017 /* ------------------------------------------------------------ */ |
1018 /** | 1018 /** |
1019 * @see org.eclipse.jetty.continuation.Continuation#getServletResponse() | 1019 * @see org.eclipse.jetty.continuation.Continuation#getServletResponse() |
1020 */ | 1020 */ |
1021 public ServletResponse getServletResponse() | 1021 public ServletResponse getServletResponse() |
1022 { | 1022 { |
1023 if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null) | 1023 if (_responseWrapped && _event!=null && _event.getSuppliedResponse()!=null) |
1024 return _event.getSuppliedResponse(); | 1024 return _event.getSuppliedResponse(); |
1025 return _connection.getResponse(); | 1025 return _connection.getResponse(); |
1026 } | 1026 } |
1027 | 1027 |
1028 /* ------------------------------------------------------------ */ | 1028 /* ------------------------------------------------------------ */ |
1029 /** | 1029 /** |
1030 * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String) | 1030 * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String) |
1031 */ | 1031 */ |
1032 public Object getAttribute(String name) | 1032 public Object getAttribute(String name) |
1033 { | 1033 { |
1034 return _connection.getRequest().getAttribute(name); | 1034 return _connection.getRequest().getAttribute(name); |
1035 } | 1035 } |
1036 | 1036 |
1037 /* ------------------------------------------------------------ */ | 1037 /* ------------------------------------------------------------ */ |
1038 /** | 1038 /** |
1039 * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String) | 1039 * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String) |
1040 */ | 1040 */ |
1041 public void removeAttribute(String name) | 1041 public void removeAttribute(String name) |
1042 { | 1042 { |
1043 _connection.getRequest().removeAttribute(name); | 1043 _connection.getRequest().removeAttribute(name); |
1044 } | 1044 } |
1045 | 1045 |
1046 /* ------------------------------------------------------------ */ | 1046 /* ------------------------------------------------------------ */ |
1047 /** | 1047 /** |
1048 * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object) | 1048 * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object) |
1049 */ | 1049 */ |
1050 public void setAttribute(String name, Object attribute) | 1050 public void setAttribute(String name, Object attribute) |
1051 { | 1051 { |
1052 _connection.getRequest().setAttribute(name,attribute); | 1052 _connection.getRequest().setAttribute(name,attribute); |
1053 } | 1053 } |
1054 | 1054 |
1055 /* ------------------------------------------------------------ */ | 1055 /* ------------------------------------------------------------ */ |
1056 /** | 1056 /** |
1057 * @see org.eclipse.jetty.continuation.Continuation#undispatch() | 1057 * @see org.eclipse.jetty.continuation.Continuation#undispatch() |
1058 */ | 1058 */ |
1059 public void undispatch() | 1059 public void undispatch() |
1060 { | 1060 { |
1061 if (isSuspended()) | 1061 if (isSuspended()) |
1062 { | 1062 { |
1063 if (LOG.isDebugEnabled()) | 1063 if (LOG.isDebugEnabled()) |
1064 throw new ContinuationThrowable(); | 1064 throw new ContinuationThrowable(); |
1065 else | 1065 else |
1066 throw __exception; | 1066 throw __exception; |
1067 } | 1067 } |
1068 throw new IllegalStateException("!suspended"); | 1068 throw new IllegalStateException("!suspended"); |
1069 } | 1069 } |
1070 | 1070 |
1071 /* ------------------------------------------------------------ */ | 1071 /* ------------------------------------------------------------ */ |
1072 /* ------------------------------------------------------------ */ | 1072 /* ------------------------------------------------------------ */ |
1073 public class AsyncTimeout extends Timeout.Task implements Runnable | 1073 public class AsyncTimeout extends Timeout.Task implements Runnable |
1074 { | 1074 { |
1075 @Override | 1075 @Override |
1076 public void expired() | 1076 public void expired() |
1077 { | 1077 { |
1078 AsyncContinuation.this.expired(); | 1078 AsyncContinuation.this.expired(); |
1079 } | 1079 } |
1080 | 1080 |
1081 @Override | 1081 @Override |
1082 public void run() | 1082 public void run() |
1083 { | 1083 { |
1084 AsyncContinuation.this.expired(); | 1084 AsyncContinuation.this.expired(); |
1085 } | 1085 } |
1086 } | 1086 } |
1087 | 1087 |
1088 /* ------------------------------------------------------------ */ | 1088 /* ------------------------------------------------------------ */ |
1089 /* ------------------------------------------------------------ */ | 1089 /* ------------------------------------------------------------ */ |
1090 public class AsyncEventState extends AsyncEvent | 1090 public class AsyncEventState extends AsyncEvent |
1091 { | 1091 { |
1092 private final ServletContext _suspendedContext; | 1092 private final ServletContext _suspendedContext; |
1093 private ServletContext _dispatchContext; | 1093 private ServletContext _dispatchContext; |
1094 private String _pathInContext; | 1094 private String _pathInContext; |
1095 private Timeout.Task _timeout= new AsyncTimeout(); | 1095 private Timeout.Task _timeout= new AsyncTimeout(); |
1096 | 1096 |
1097 public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response) | 1097 public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response) |
1098 { | 1098 { |
1099 super(AsyncContinuation.this, request,response); | 1099 super(AsyncContinuation.this, request,response); |
1100 _suspendedContext=context; | 1100 _suspendedContext=context; |
1101 // Get the base request So we can remember the initial paths | 1101 // Get the base request So we can remember the initial paths |
1102 Request r=_connection.getRequest(); | 1102 Request r=_connection.getRequest(); |
1103 | 1103 |
1104 // If we haven't been async dispatched before | 1104 // If we haven't been async dispatched before |
1105 if (r.getAttribute(AsyncContext.ASYNC_REQUEST_URI)==null) | 1105 if (r.getAttribute(AsyncContext.ASYNC_REQUEST_URI)==null) |
1106 { | 1106 { |
1107 // We are setting these attributes during startAsync, when the spec implies that | 1107 // We are setting these attributes during startAsync, when the spec implies that |
1108 // they are only available after a call to AsyncContext.dispatch(...); | 1108 // they are only available after a call to AsyncContext.dispatch(...); |
1109 | 1109 |
1110 // have we been forwarded before? | 1110 // have we been forwarded before? |
1111 String uri=(String)r.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI); | 1111 String uri=(String)r.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI); |
1112 if (uri!=null) | 1112 if (uri!=null) |
1113 { | 1113 { |
1114 r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,uri); | 1114 r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,uri); |
1115 r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH)); | 1115 r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH)); |
1116 r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH)); | 1116 r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH)); |
1117 r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getAttribute(RequestDispatcher.FORWARD_PATH_INFO)); | 1117 r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getAttribute(RequestDispatcher.FORWARD_PATH_INFO)); |
1118 r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING)); | 1118 r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING)); |
1119 } | 1119 } |
1120 else | 1120 else |
1121 { | 1121 { |
1122 r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,r.getRequestURI()); | 1122 r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,r.getRequestURI()); |
1123 r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getContextPath()); | 1123 r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getContextPath()); |
1124 r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getServletPath()); | 1124 r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getServletPath()); |
1125 r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getPathInfo()); | 1125 r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getPathInfo()); |
1126 r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getQueryString()); | 1126 r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getQueryString()); |
1127 } | 1127 } |
1128 } | 1128 } |
1129 } | 1129 } |
1130 | 1130 |
1131 public ServletContext getSuspendedContext() | 1131 public ServletContext getSuspendedContext() |
1132 { | 1132 { |
1133 return _suspendedContext; | 1133 return _suspendedContext; |
1134 } | 1134 } |
1135 | 1135 |
1136 public ServletContext getDispatchContext() | 1136 public ServletContext getDispatchContext() |
1137 { | 1137 { |
1138 return _dispatchContext; | 1138 return _dispatchContext; |
1139 } | 1139 } |
1140 | 1140 |
1141 public ServletContext getServletContext() | 1141 public ServletContext getServletContext() |
1142 { | 1142 { |
1143 return _dispatchContext==null?_suspendedContext:_dispatchContext; | 1143 return _dispatchContext==null?_suspendedContext:_dispatchContext; |
1144 } | 1144 } |
1145 | 1145 |
1146 public void setPath(String path) | 1146 public void setPath(String path) |
1147 { | 1147 { |
1148 _pathInContext=path; | 1148 _pathInContext=path; |
1149 } | 1149 } |
1150 | 1150 |
1151 /* ------------------------------------------------------------ */ | 1151 /* ------------------------------------------------------------ */ |
1152 /** | 1152 /** |
1153 * @return The path in the context | 1153 * @return The path in the context |
1154 */ | 1154 */ |
1155 public String getPath() | 1155 public String getPath() |
1156 { | 1156 { |
1157 return _pathInContext; | 1157 return _pathInContext; |
1158 } | 1158 } |
1159 } | 1159 } |
1160 } | 1160 } |