fix(http): initialize libcurl global state once at startup#33
Open
ratazzi wants to merge 1 commit into
Open
Conversation
curl_easy_init() falls back to lazy curl_global_init(), which is documented as not thread-safe. The download manager spawns worker threads that each create easy handles, so when the first curl call of the process happened inside those workers (e.g. a provision consisting only of remote_file resources), several threads could race the global initialization, including OpenSSL setup. Additionally, KMSClient called curl_global_init in init and curl_global_cleanup in deinit. The pair is neither reference-counted nor thread-safe, so destroying one client while any other transfer was in flight tore down shared global state. Call curl_global_init(CURL_GLOBAL_ALL) once in main while the process is still single-threaded, pair it with curl_global_cleanup on exit, and drop the per-instance init/cleanup from KMSClient.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two related issues with libcurl global state:
The main HTTP client never called
curl_global_init(), relying oncurl_easy_init()'s lazy fallback, which is documented as not thread-safe. The download manager spawns worker threads that each create easy handles, so when the first curl call of the process happened inside those workers (e.g. a provision consisting only ofremote_fileresources), multiple threads could race the global initialization, including OpenSSL setup.KMSClientcalledcurl_global_initininitandcurl_global_cleanupindeinit. The pair is neither reference-counted nor thread-safe, so destroying one client while any other transfer was in flight tore down shared global state under it.Fix
curl_global_init(CURL_GLOBAL_ALL)once inmainwhile the process is still single-threaded, paired withcurl_global_cleanupon exit.CURL_GLOBAL_ALLconstant tocurl.zig(replacing the magic0x03).KMSClient.Testing
zig build testpasses;hola --versionand a provision run with the HTTP stack work as before.