Cleanup the RetryTimeoutCallback().
When canceling a request or destroying the LibcurlHttpFetcher, a
RetryTimeoutCallback callback could be leaked if the fetcher was
waiting on a network retry.
This patch keeps track of the retry callback and cancels it on CleanUp,
making sure the callback is not leaked.
Bug: 34178297
Test: Added unittest to trigger this case.
Change-Id: I7016641a7f31429933779e55c77cbabb6289c3dd
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index ee31c8d..63c67c0 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -393,7 +393,7 @@
http_response_code_ == 0 &&
no_network_retry_count_ < no_network_max_retries_) {
no_network_retry_count_++;
- MessageLoop::current()->PostDelayedTask(
+ retry_task_id_ = MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
base::Unretained(this)),
@@ -419,7 +419,7 @@
if (HasProxy()) {
// We have another proxy. Retry immediately.
LOG(INFO) << "Retrying with next proxy setting";
- MessageLoop::current()->PostTask(
+ retry_task_id_ = MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
base::Unretained(this)));
@@ -446,7 +446,7 @@
}
// Need to restart transfer
LOG(INFO) << "Restarting transfer to download the remaining bytes";
- MessageLoop::current()->PostDelayedTask(
+ retry_task_id_ = MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&LibcurlHttpFetcher::RetryTimeoutCallback,
base::Unretained(this)),
@@ -624,6 +624,7 @@
}
void LibcurlHttpFetcher::RetryTimeoutCallback() {
+ retry_task_id_ = MessageLoop::kTaskIdNull;
if (transfer_paused_) {
restart_transfer_on_unpause_ = true;
return;
@@ -648,6 +649,9 @@
}
void LibcurlHttpFetcher::CleanUp() {
+ MessageLoop::current()->CancelTask(retry_task_id_);
+ retry_task_id_ = MessageLoop::kTaskIdNull;
+
MessageLoop::current()->CancelTask(timeout_id_);
timeout_id_ = MessageLoop::kTaskIdNull;