|
21 | 21 | importcom.ning.http.util.AsyncHttpProviderUtils; |
22 | 22 | importcom.ning.http.util.ProxyUtils; |
23 | 23 | importjava.io.IOException; |
24 | | -importjava.util.HashSet; |
25 | | -importjava.util.Set; |
26 | 24 | importorg.glassfish.grizzly.CloseListener; |
27 | 25 | importorg.glassfish.grizzly.CloseType; |
28 | 26 | importorg.glassfish.grizzly.Closeable; |
@@ -86,8 +84,8 @@ public final class HttpTransactionContext { |
86 | 84 | /** |
87 | 85 | * <tt>true</tt> if the request is fully sent, or <tt>false</tt>otherwise. |
88 | 86 | */ |
89 | | -volatilebooleanisRequestFullySent; |
90 | | -Set<CompletionHandler<HttpTransactionContext>>reqFullySentHandlers; |
| 87 | +privatebooleanisRequestFullySent; |
| 88 | +privateCleanupTaskcleanupTask; |
91 | 89 |
|
92 | 90 | privatefinalCloseListenerlistener =newCloseListener<Closeable,CloseType>() { |
93 | 91 | @Override |
@@ -125,24 +123,9 @@ static void cleanupTransaction(final HttpContext httpCtx, |
125 | 123 |
|
126 | 124 | asserthttpTxContext !=null; |
127 | 125 |
|
128 | | -if (httpTxContext.isRequestFullySent) { |
129 | | -cleanupTransaction(httpCtx,httpTxContext); |
130 | | -completionHandler.completed(httpTxContext); |
131 | | - }else { |
132 | | -httpTxContext.addRequestSentCompletionHandler(completionHandler); |
133 | | -if (httpTxContext.isRequestFullySent && |
134 | | -httpTxContext.removeRequestSentCompletionHandler(completionHandler)) { |
135 | | -completionHandler.completed(httpTxContext); |
136 | | - } |
137 | | - } |
| 126 | +httpTxContext.scheduleCleanup(httpCtx,completionHandler); |
138 | 127 | } |
139 | 128 |
|
140 | | -staticvoidcleanupTransaction(finalHttpContexthttpCtx, |
141 | | -finalHttpTransactionContexthttpTxContext) { |
142 | | -httpCtx.getCloseable().removeCloseListener(httpTxContext.listener); |
143 | | -REQUEST_STATE_ATTR.remove(httpCtx); |
144 | | - } |
145 | | - |
146 | 129 | staticHttpTransactionContextcurrentTransaction( |
147 | 130 | finalHttpHeaderhttpHeader) { |
148 | 131 | returncurrentTransaction(httpHeader.getProcessingState().getHttpContext()); |
@@ -269,44 +252,56 @@ void closeConnection() { |
269 | 252 | connection.closeSilently(); |
270 | 253 | } |
271 | 254 |
|
272 | | -privatesynchronizedvoidaddRequestSentCompletionHandler( |
| 255 | +privatevoidscheduleCleanup(finalHttpContexthttpCtx, |
273 | 256 | finalCompletionHandler<HttpTransactionContext>completionHandler) { |
274 | | -if (reqFullySentHandlers ==null) { |
275 | | -reqFullySentHandlers =newHashSet<>(); |
| 257 | +synchronized (this) { |
| 258 | +if (!isRequestFullySent) { |
| 259 | +assertcleanupTask ==null;// scheduleCleanup should be called only once |
| 260 | +cleanupTask =newCleanupTask(httpCtx,completionHandler); |
| 261 | +return; |
| 262 | + } |
276 | 263 | } |
277 | | -reqFullySentHandlers.add(completionHandler); |
278 | | - } |
279 | 264 |
|
280 | | -privatesynchronizedbooleanremoveRequestSentCompletionHandler( |
281 | | -finalCompletionHandler<HttpTransactionContext>completionHandler) { |
282 | | -returnreqFullySentHandlers !=null |
283 | | - ?reqFullySentHandlers.remove(completionHandler) |
284 | | - :false; |
| 265 | +assertisRequestFullySent; |
| 266 | +cleanup(httpCtx); |
| 267 | +completionHandler.completed(this); |
285 | 268 | } |
286 | 269 |
|
287 | | -booleanisRequestFullySent() { |
288 | | -returnisRequestFullySent; |
| 270 | +privatevoidcleanup(finalHttpContexthttpCtx) { |
| 271 | +httpCtx.getCloseable().removeCloseListener(listener); |
| 272 | +REQUEST_STATE_ATTR.remove(httpCtx); |
289 | 273 | } |
290 | 274 |
|
291 | 275 | @SuppressWarnings("unchecked") |
292 | 276 | voidonRequestFullySent() { |
293 | | -this.isRequestFullySent =true; |
294 | | - |
295 | | -Object[]handlers =null; |
296 | 277 | synchronized (this) { |
297 | | -if (reqFullySentHandlers !=null) { |
298 | | -handlers =reqFullySentHandlers.toArray(); |
299 | | -reqFullySentHandlers =null; |
| 278 | +if (isRequestFullySent) { |
| 279 | +return; |
300 | 280 | } |
| 281 | + |
| 282 | +isRequestFullySent =true; |
301 | 283 | } |
302 | 284 |
|
303 | | -if (handlers !=null) { |
304 | | -for (Objecto :handlers) { |
305 | | -try { |
306 | | - ((CompletionHandler<HttpTransactionContext>)o).completed(this); |
307 | | - }catch (Exceptione) { |
308 | | - } |
309 | | - } |
| 285 | +if (cleanupTask !=null) { |
| 286 | +cleanupTask.run(); |
| 287 | + } |
| 288 | + } |
| 289 | + |
| 290 | +privateclassCleanupTaskimplementsRunnable { |
| 291 | +privatefinalHttpContexthttpCtx; |
| 292 | +privatefinalCompletionHandler<HttpTransactionContext>completionHandler; |
| 293 | + |
| 294 | +privateCleanupTask(finalHttpContexthttpCtx, |
| 295 | +finalCompletionHandler<HttpTransactionContext>completionHandler) { |
| 296 | +this.httpCtx =httpCtx; |
| 297 | +this.completionHandler =completionHandler; |
| 298 | + } |
| 299 | + |
| 300 | +@Override |
| 301 | +publicvoidrun() { |
| 302 | +cleanup(httpCtx); |
| 303 | +completionHandler.completed(HttpTransactionContext.this); |
310 | 304 | } |
| 305 | + |
311 | 306 | } |
312 | 307 | }// END HttpTransactionContext |