Remove easy handles before curl_multi_cleanup
commitde9dba2d8f8464a7d35fd34a699e7dfcead63dfd
authorShaunak Kishore <kshaunak@fb.com>
Tue, 17 Aug 2021 14:37:19 +0000 (17 07:37 -0700)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Tue, 17 Aug 2021 14:38:46 +0000 (17 07:38 -0700)
tree3443f762990d9475cda2f3b32dea1026321f9cd4
parentb6477f0e9b8c7ead4510dda670e0b0ae7a424768
Remove easy handles before curl_multi_cleanup

Summary:
Before destroying a curl multi handle, we must detach all easy handles attached to it: https://curl.se/libcurl/c/curl_multi_cleanup.html

Today, we don't respect this constraint at all. Let's fix that.

We destroy curl multi handles in two cases: during the request, when its refcount goes to 0, and at the end of the request, on a call to sweep. In both of these cases, we don't place any ordering invariant between destroying multi handles and their attached easy handles today - we can destroy the multi handles with easy handles attached, or worse, destroy the easy handle, then destroy the multi handle with a dangling reference!

We fix these cases by tracking a bidirectional mapping between multi handles and their attached easy handle. Whenever we destroy either handle, we first detach all edges incident to it. We need to be a little bit careful on sweep, because it happens after we start to tear down request memory. To handle that case, I added a "leak" param to CurlMultiResource::remove that lets us detach the edge without allocating memory or calling destructors. I also tied the add/remove metadata operations to the underlying curl operations, so that we don't add/remove an edge when the curl operation fails.

Reviewed By: ricklavoie

Differential Revision: D30344219

fbshipit-source-id: 553a7dae54a96737f82180d3b9abec317e81e8a4
hphp/runtime/ext/curl/curl-multi-await.cpp
hphp/runtime/ext/curl/curl-multi-resource.cpp
hphp/runtime/ext/curl/curl-multi-resource.h
hphp/runtime/ext/curl/curl-resource.cpp
hphp/runtime/ext/curl/curl-resource.h
hphp/runtime/ext/curl/ext_curl.cpp