diff --git a/exporters/otlp/src/otlp_http_client.cc b/exporters/otlp/src/otlp_http_client.cc index 12731120c1..1818b2132e 100644 --- a/exporters/otlp/src/otlp_http_client.cc +++ b/exporters/otlp/src/otlp_http_client.cc @@ -847,20 +847,20 @@ void OtlpHttpClient::ReleaseSession( { bool has_session = false; - { - std::lock_guard guard{session_manager_lock_}; + std::lock_guard guard{session_manager_lock_}; - auto session_iter = running_sessions_.find(&session); - if (session_iter != running_sessions_.end()) - { - // Move session and handle into gc list, and they will be destroyed later - gc_sessions_.emplace_back(std::move(session_iter->second)); - running_sessions_.erase(session_iter); + auto session_iter = running_sessions_.find(&session); + if (session_iter != running_sessions_.end()) + { + // Move session and handle into gc list, and they will be destroyed later + gc_sessions_.emplace_back(std::move(session_iter->second)); + running_sessions_.erase(session_iter); - has_session = true; - } + has_session = true; } + // Call session_waker_.notify_all() with session_manager_lock_ locked to keep session_waker_ + // available when destroying OtlpHttpClient if (has_session) { session_waker_.notify_all(); diff --git a/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h b/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h index cc3aec47b2..45f4683973 100644 --- a/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h @@ -41,13 +41,15 @@ class SimpleLogProcessor : public LogProcessor bool Shutdown( std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + bool IsShutdown() const noexcept; + private: // The configured exporter std::unique_ptr exporter_; // The lock used to ensure the exporter is not called concurrently opentelemetry::common::SpinLockMutex lock_; - // The atomic boolean flag to ensure the ShutDown() function is only called once - std::atomic_flag shutdown_latch_ = ATOMIC_FLAG_INIT; + // The atomic boolean to ensure the ShutDown() function is only called once + std::atomic is_shutdown_; }; } // namespace logs } // namespace sdk diff --git a/sdk/src/logs/logger_context.cc b/sdk/src/logs/logger_context.cc index b0025ff724..dd26d7e508 100644 --- a/sdk/src/logs/logger_context.cc +++ b/sdk/src/logs/logger_context.cc @@ -44,7 +44,7 @@ bool LoggerContext::ForceFlush(std::chrono::microseconds timeout) noexcept bool LoggerContext::Shutdown(std::chrono::microseconds timeout) noexcept { - return processor_->ForceFlush(timeout); + return processor_->Shutdown(timeout); } } // namespace logs diff --git a/sdk/src/logs/simple_log_processor.cc b/sdk/src/logs/simple_log_processor.cc index 6e2fde9f14..c9ba4c7895 100644 --- a/sdk/src/logs/simple_log_processor.cc +++ b/sdk/src/logs/simple_log_processor.cc @@ -17,7 +17,7 @@ namespace logs * @param exporter the configured exporter where log records are sent */ SimpleLogProcessor::SimpleLogProcessor(std::unique_ptr &&exporter) - : exporter_(std::move(exporter)) + : exporter_(std::move(exporter)), is_shutdown_(false) {} std::unique_ptr SimpleLogProcessor::MakeRecordable() noexcept @@ -51,13 +51,19 @@ bool SimpleLogProcessor::ForceFlush(std::chrono::microseconds timeout) noexcept bool SimpleLogProcessor::Shutdown(std::chrono::microseconds timeout) noexcept { // Should only shutdown exporter ONCE. - if (!shutdown_latch_.test_and_set(std::memory_order_acquire) && exporter_ != nullptr) + if (!is_shutdown_.exchange(true, std::memory_order_acq_rel) && exporter_ != nullptr) { return exporter_->Shutdown(timeout); } return true; } + +bool SimpleLogProcessor::IsShutdown() const noexcept +{ + return is_shutdown_.load(std::memory_order_acquire); +} + } // namespace logs } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/logs/logger_provider_sdk_test.cc b/sdk/test/logs/logger_provider_sdk_test.cc index 36bbb4a0ec..3f02ace7e2 100644 --- a/sdk/test/logs/logger_provider_sdk_test.cc +++ b/sdk/test/logs/logger_provider_sdk_test.cc @@ -108,12 +108,14 @@ TEST(LoggerProviderSDK, GetResource) TEST(LoggerProviderSDK, Shutdown) { std::unique_ptr processor(new SimpleLogProcessor(nullptr)); + SimpleLogProcessor *processor_ptr = processor.get(); std::vector> processors; processors.push_back(std::move(processor)); LoggerProvider lp(std::make_shared(std::move(processors))); EXPECT_TRUE(lp.Shutdown()); + EXPECT_TRUE(processor_ptr->IsShutdown()); // It's safe to shutdown again EXPECT_TRUE(lp.Shutdown());