diff --git a/src/datadog/curl.cpp b/src/datadog/curl.cpp index 3f62445f..05fef196 100644 --- a/src/datadog/curl.cpp +++ b/src/datadog/curl.cpp @@ -208,7 +208,7 @@ class CurlImpl { }; void run(); - void handle_message(const CURLMsg &); + void handle_message(const CURLMsg &, std::unique_lock &); CURLcode log_on_error(CURLcode result); CURLMcode log_on_error(CURLMcode result); @@ -476,7 +476,7 @@ void CurlImpl::run() { // us to handle. Handle any pending messages. while ((message = curl_.multi_info_read(multi_handle_, &num_messages_remaining))) { - handle_message(*message); + handle_message(*message, lock); } const int max_wait_milliseconds = 10 * 1000; @@ -514,7 +514,8 @@ void CurlImpl::run() { curl_.global_cleanup(); } -void CurlImpl::handle_message(const CURLMsg &message) { +void CurlImpl::handle_message(const CURLMsg &message, + std::unique_lock &lock) { if (message.msg != CURLMSG_DONE) { return; } @@ -536,8 +537,10 @@ void CurlImpl::handle_message(const CURLMsg &message) { error_message += curl_.easy_strerror(result); error_message += "): "; error_message += request.error_buffer; + lock.unlock(); request.on_error( Error{Error::CURL_REQUEST_FAILURE, std::move(error_message)}); + lock.lock(); } else { long status; if (log_on_error(curl_.easy_getinfo_response_code(request_handle, @@ -545,8 +548,10 @@ void CurlImpl::handle_message(const CURLMsg &message) { status = -1; } HeaderReader reader(&request.response_headers_lower); + lock.unlock(); request.on_response(static_cast(status), reader, std::move(request.response_body)); + lock.lock(); } log_on_error(curl_.multi_remove_handle(multi_handle_, request_handle)); diff --git a/src/datadog/http_client.h b/src/datadog/http_client.h index df340d43..2a7310ac 100644 --- a/src/datadog/http_client.h +++ b/src/datadog/http_client.h @@ -43,7 +43,8 @@ class HTTPClient { // a response is delivered (even if that response contains an error HTTP // response status). Invoke the specified `on_error` if an error occurs // outside of HTTP, such as a connection failure. If an error occurs while - // preparing the request, return an `Error`. + // preparing the request, return an `Error`. The behavior is undefined if + // either of `on_response` or `on_error` throws an exception. virtual Expected post(const URL& url, HeadersSetter set_headers, std::string body, ResponseHandler on_response, ErrorHandler on_error) = 0; diff --git a/test/test_tracer.cpp b/test/test_tracer.cpp index 11c3ca8c..9947ddbf 100644 --- a/test/test_tracer.cpp +++ b/test/test_tracer.cpp @@ -1017,7 +1017,7 @@ TEST_CASE("128-bit trace IDs") { // Use a clock that always returns a hard-coded `TimePoint`. // May 6, 2010 14:45:13 America/New_York const std::time_t flash_crash = 1273171513; - const Clock clock = [flash_crash]() { + const Clock clock = []() { TimePoint result; result.wall = std::chrono::system_clock::from_time_t(flash_crash); return result; diff --git a/test/test_tracer_telemetry.cpp b/test/test_tracer_telemetry.cpp index 430a1860..5b92b88b 100644 --- a/test/test_tracer_telemetry.cpp +++ b/test/test_tracer_telemetry.cpp @@ -14,7 +14,7 @@ using namespace datadog::tracing; TEST_CASE("Tracer telemetry") { const std::time_t mock_time = 1672484400; - const Clock clock = [mock_time]() { + const Clock clock = []() { TimePoint result; result.wall = std::chrono::system_clock::from_time_t(mock_time); return result;