Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
553b948
[BUG] Check what curl_slist_append and curl_multi_init return
thc1006 Aug 11, 2026
6872752
[TEST] Make the allocation failure case independent of the libcurl in…
thc1006 Aug 11, 2026
6e5a495
[TEST] Hold what a client without a multi handle does with a request
thc1006 Aug 11, 2026
59f550d
[TEST] Cover the synchronous refusal and the instrumented constructor
thc1006 Aug 11, 2026
a1f3419
[BUG] Stop the IO thread spinning when the multi handle cannot be cre…
thc1006 Aug 11, 2026
bc3dc07
[TEST] Take the include set include-what-you-use asks for
thc1006 Aug 11, 2026
d903452
[BUG] Stop the IO thread spinning while it has no multi handle
thc1006 Aug 13, 2026
fe0d1ce
[BUG] Create the multi handle after curl_global_init has run
thc1006 Aug 13, 2026
be0d3fd
[TEST] Describe what the case holds rather than what it used to find
thc1006 Aug 13, 2026
7599add
[BUG] Wait in slices, and keep the null handle out of curl_multi_info…
thc1006 Aug 13, 2026
6dfd4b1
[BUG] Keep the phases that need a multi handle from running without one
thc1006 Aug 13, 2026
3abb874
[BUG] Report the missing handle wait as a wait
thc1006 Aug 13, 2026
6e392a9
[CHORE] Say each invariant once in the comments
thc1006 Aug 13, 2026
b0e33af
[TEST] Hold the phase gate with a request queued during the outage
thc1006 Aug 13, 2026
3e6063b
[BUG] Refuse a request whose easy handle was never created
thc1006 Aug 13, 2026
051fe74
[BUG] Do not retire the IO thread while a queue still holds work
thc1006 Aug 13, 2026
ff09136
Revert "[BUG] Do not retire the IO thread while a queue still holds w…
thc1006 Aug 14, 2026
5ca9dab
[BUG] Describe a failed easy handle once, and ask the case for once
thc1006 Aug 14, 2026
f7eaebc
[BUG] Keep the IO thread while it still owes somebody an answer
thc1006 Aug 14, 2026
e2331e3
[BUG] Do not call a multi function without a multi handle
thc1006 Aug 14, 2026
7811a6f
[TEST] Build the client without a multi handle rather than taking one…
thc1006 Aug 14, 2026
14cd974
[BUG] Release what is still queued when the client goes
thc1006 Aug 14, 2026
f09ff47
[BUG] Take out of the retry queue what is not going to be retried
thc1006 Aug 14, 2026
b98ef29
[TEST] Do not let a case leave global state behind it
thc1006 Aug 14, 2026
fe21650
[TEST] Fail the second list node, not just the first
thc1006 Aug 14, 2026
acc4205
Say in the changelog what else this fixes
thc1006 Aug 14, 2026
5c89d79
[TEST] Destroy the client with a retry still pending, and nobody canc…
thc1006 Aug 14, 2026
c3e8fac
[TEST] Watch the retry from outside the client, not from inside its q…
thc1006 Aug 14, 2026
6d505f3
[CHORE] Say what the code does, and let the cases outlive what talks …
thc1006 Aug 14, 2026
b54e01a
Take the include include-what-you-use asks for
thc1006 Aug 14, 2026
e37fbf3
Take the other include include-what-you-use asks for
thc1006 Aug 15, 2026
f6a3700
[TEST] Refuse a header append by name, not by allocation size
thc1006 Aug 15, 2026
a5ea615
[BUG] Ask one question about a retry entry, from both places that ask it
thc1006 Aug 15, 2026
3de8ca2
[BUG] Do not retire on a queue that filled up while this thread was d…
thc1006 Aug 15, 2026
6098d3e
[BUG] Report a failed multi cleanup after the mutex, not under it
thc1006 Aug 16, 2026
fb70655
[TEST] Cover the TLS version range and cipher list that Setup() applies
thc1006 Aug 26, 2026
916bd48
[TEST] Name every constructor argument in the new cases
thc1006 Aug 27, 2026
6640ce0
[BUGFIX] Declare the global initializer before the multi handle
thc1006 Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ Increment the:
deprecated C headers (`stdint.h`, `stddef.h`, `stdlib.h`, `string.h`,
`stdio.h`, `ctype.h`, `limits.h`, `assert.h`) with their C++ equivalents
([#4349](https://github.com/open-telemetry/opentelemetry-cpp/pull/4349))
* [BUG] Check what curl_easy_init, curl_slist_append and curl_multi_init return
instead of treating a failed allocation as success
[#4404](https://github.com/open-telemetry/opentelemetry-cpp/issues/4404)
* [BUG] Stop the curl IO thread spinning, flooding the log, and refusing to be
destroyed, when the multi handle cannot be created
[#4404](https://github.com/open-telemetry/opentelemetry-cpp/issues/4404)
* [BUG] Keep the curl IO thread from retiring while a request it accepted is
still waiting to be scheduled, and release the easy handles and header lists
left queued when the client is destroyed
[#4404](https://github.com/open-telemetry/opentelemetry-cpp/issues/4404)
* [BUG] Take an operation that was cancelled or torn down out of the curl retry
queue, and check what curl_multi_remove_handle and curl_multi_add_handle
return when a retry is scheduled
[#4404](https://github.com/open-telemetry/opentelemetry-cpp/issues/4404)

* [CONFIGURATION] Add SDK component builder interfaces to the registry
[#4358](https://github.com/open-telemetry/opentelemetry-cpp/issues/4358)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,22 @@ class HttpClient : public opentelemetry::ext::http::client::HttpClient
bool doAbortSessions();
bool doRemoveSessions();
bool doRetrySessions(bool report_all);
void resetMultiHandle();
// Returns true if the background thread still owes somebody an answer. Drops what it finds
// that nothing can be owed for, so that a queue which is merely not empty does not read as
// work. Call it on the background thread only: it prunes pending_to_retry_sessions_, which
// has no lock because that thread is the only one that touches it.
bool hasActionableWork();
// Cleans up the multi handle if there is one, and leaves none behind either way. Call it
// holding multi_handle_m_. It answers with what curl_multi_cleanup said rather than reporting
// it, because reporting reaches a log handler the application supplies, and one that comes back
// into this client would do it while the caller still holds that mutex.
CURLMcode ReleaseMultiHandle();
// Returns true if the client has a multi handle afterwards.
bool resetMultiHandle();

// Declared before multi_handle_ on purpose: members are initialised in declaration
// order, and curl_multi_init() may not run before curl_global_init().
nostd::shared_ptr<HttpCurlGlobalInitializer> curl_global_initializer_;

std::mutex multi_handle_m_;
CURLM *multi_handle_;
Expand All @@ -387,8 +402,10 @@ class HttpClient : public opentelemetry::ext::http::client::HttpClient

std::chrono::milliseconds background_thread_wait_for_;
std::atomic<bool> is_shutdown_{false};

nostd::shared_ptr<HttpCurlGlobalInitializer> curl_global_initializer_;
// Raised by every producer. curl_multi_wakeup is how the background thread is woken out of
// curl_multi_poll and it needs a multi handle, so the wait taken when there is none watches
// this instead.
std::atomic<uint64_t> wakeup_generation_{0};
};

} // namespace curl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ class HttpOperation

char curl_error_message_[CURL_ERROR_SIZE]{};
HttpCurlEasyResource curl_resource_;
CURLcode last_curl_result_{CURLE_OK}; // Curl result OR HTTP status code if successful
CURLcode last_curl_result_{CURLE_OK}; // Curl result OR HTTP status code if successful
CURLcode construction_result_{CURLE_OK}; // Non-OK if setup failed; Send() refuses on it

opentelemetry::ext::http::client::EventHandler *event_handle_{nullptr};

Expand Down
Loading
Loading