Untag and stop watch on network sockets before closing them.
am: 13e9518b53
Change-Id: I74dfec0bcff5f48a5580d6cef8994b521214baaa
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index 9dcd654..9d9f58b 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -68,6 +68,32 @@
} // namespace
+// static
+int LibcurlHttpFetcher::LibcurlCloseSocketCallback(void* clientp,
+ curl_socket_t item) {
+#ifdef __ANDROID__
+ qtaguid_untagSocket(item);
+#endif // __ANDROID__
+ LibcurlHttpFetcher* fetcher = static_cast<LibcurlHttpFetcher*>(clientp);
+ // Stop watching the socket before closing it.
+ for (size_t t = 0; t < arraysize(fetcher->fd_task_maps_); ++t) {
+ const auto fd_task_pair = fetcher->fd_task_maps_[t].find(item);
+ if (fd_task_pair != fetcher->fd_task_maps_[t].end()) {
+ if (!MessageLoop::current()->CancelTask(fd_task_pair->second)) {
+ LOG(WARNING) << "Error canceling the watch task "
+ << fd_task_pair->second << " for "
+ << (t ? "writing" : "reading") << " the fd " << item;
+ }
+ fetcher->fd_task_maps_[t].erase(item);
+ }
+ }
+
+ // Documentation for this callback says to return 0 on success or 1 on error.
+ if (!IGNORE_EINTR(close(item)))
+ return 0;
+ return 1;
+}
+
LibcurlHttpFetcher::LibcurlHttpFetcher(ProxyResolver* proxy_resolver,
HardwareInterface* hardware)
: HttpFetcher(proxy_resolver), hardware_(hardware) {
@@ -126,9 +152,12 @@
CHECK(curl_handle_);
ignore_failure_ = false;
- // Tag the socket for network usage stats.
+ // Tag and untag the socket for network usage stats.
curl_easy_setopt(
curl_handle_, CURLOPT_SOCKOPTFUNCTION, LibcurlSockoptCallback);
+ curl_easy_setopt(
+ curl_handle_, CURLOPT_CLOSESOCKETFUNCTION, LibcurlCloseSocketCallback);
+ curl_easy_setopt(curl_handle_, CURLOPT_CLOSESOCKETDATA, this);
CHECK(HasProxy());
bool is_direct = (GetCurrentProxy() == kNoProxy);
diff --git a/libcurl_http_fetcher.h b/libcurl_http_fetcher.h
index 5b16811..61871c9 100644
--- a/libcurl_http_fetcher.h
+++ b/libcurl_http_fetcher.h
@@ -107,6 +107,10 @@
}
private:
+ // libcurl's CURLOPT_CLOSESOCKETFUNCTION callback function. Called when
+ // closing a socket created with the CURLOPT_OPENSOCKETFUNCTION callback.
+ static int LibcurlCloseSocketCallback(void* clientp, curl_socket_t item);
+
// Callback for when proxy resolution has completed. This begins the
// transfer.
void ProxiesResolved();