From 626cb898c4c0b4243494d845df9156c6ea67fd04 Mon Sep 17 00:00:00 2001 From: Will Lauer Date: Tue, 28 Jul 2020 13:12:27 -0500 Subject: [PATCH] Cancel replaced timeouts to avoid leak Fix for issue #1731. When setting the TimeoutHolder, cancel any prior timeout so that they don't leak. Previously, they would just be lost and remain in the timer until their timeout expired, which could be a long time. Previously, encountering a redirect would trigger this code, causing the old request timer to be replaced with a new one. The old timer would maintain a link back to this Future, but couldn't be canceled by this future (as its reference had been overwritten) causing the Future, is associated Response, and any AsyncResponseHandler to be retained in memory instead of being garbage collected once the request had been processed. --- .../java/org/asynchttpclient/netty/NettyResponseFuture.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java b/client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java index 9f84ada7ab..dddebfff41 100755 --- a/client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java +++ b/client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java @@ -366,7 +366,10 @@ public TimeoutsHolder getTimeoutsHolder() { } public void setTimeoutsHolder(TimeoutsHolder timeoutsHolder) { - TIMEOUTS_HOLDER_FIELD.set(this, timeoutsHolder); + TimeoutsHolder ref = TIMEOUTS_HOLDER_FIELD.getAndSet(this, timeoutsHolder); + if (ref != null) { + ref.cancel(); + } } public boolean isInAuth() {