Skip to content

Commit ba38077

Browse files
authored
[EXPORTER] Fixes tsan warnings (#3531)
1 parent ac1172e commit ba38077

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ class HttpOperation
338338
std::promise<CURLcode> result_promise;
339339
std::future<CURLcode> result_future;
340340
};
341+
friend class HttpOperationAccessor;
341342
std::unique_ptr<AsyncData> async_data_;
342343
};
343344
} // namespace curl

ext/src/http/client/curl/http_operation_curl.cc

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ namespace client
4747
namespace curl
4848
{
4949

50+
class HttpOperationAccessor
51+
{
52+
public:
53+
OPENTELEMETRY_SANITIZER_NO_THREAD static std::thread::id GetThreadId(
54+
const HttpOperation::AsyncData &async_data)
55+
{
56+
#if !(defined(OPENTELEMETRY_HAVE_THREAD_SANITIZER) && OPENTELEMETRY_HAVE_THREAD_SANITIZER)
57+
std::atomic_thread_fence(std::memory_order_acquire);
58+
#endif
59+
return async_data.callback_thread;
60+
}
61+
62+
OPENTELEMETRY_SANITIZER_NO_THREAD static void SetThreadId(HttpOperation::AsyncData &async_data,
63+
std::thread::id thread_id)
64+
{
65+
async_data.callback_thread = thread_id;
66+
#if !(defined(OPENTELEMETRY_HAVE_THREAD_SANITIZER) && OPENTELEMETRY_HAVE_THREAD_SANITIZER)
67+
std::atomic_thread_fence(std::memory_order_release);
68+
#endif
69+
}
70+
};
71+
5072
size_t HttpOperation::WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
5173
{
5274
HttpOperation *self = reinterpret_cast<HttpOperation *>(userp);
@@ -335,7 +357,7 @@ HttpOperation::~HttpOperation()
335357
case opentelemetry::ext::http::client::SessionState::Sending: {
336358
if (async_data_ && async_data_->result_future.valid())
337359
{
338-
if (async_data_->callback_thread != std::this_thread::get_id())
360+
if (HttpOperationAccessor::GetThreadId(*async_data_) != std::this_thread::get_id())
339361
{
340362
async_data_->result_future.wait();
341363
last_curl_result_ = async_data_->result_future.get();
@@ -360,7 +382,7 @@ void HttpOperation::Finish()
360382
if (async_data_ && async_data_->result_future.valid())
361383
{
362384
// We should not wait in callback from Cleanup()
363-
if (async_data_->callback_thread != std::this_thread::get_id())
385+
if (HttpOperationAccessor::GetThreadId(*async_data_) != std::this_thread::get_id())
364386
{
365387
async_data_->result_future.wait();
366388
last_curl_result_ = async_data_->result_future.get();
@@ -412,9 +434,9 @@ void HttpOperation::Cleanup()
412434
callback.swap(async_data_->callback);
413435
if (callback)
414436
{
415-
async_data_->callback_thread = std::this_thread::get_id();
437+
HttpOperationAccessor::SetThreadId(*async_data_, std::this_thread::get_id());
416438
callback(*this);
417-
async_data_->callback_thread = std::thread::id();
439+
HttpOperationAccessor::SetThreadId(*async_data_, std::thread::id());
418440
}
419441

420442
// Set value to promise to continue Finish()

0 commit comments

Comments
 (0)