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 }