@@ -547,12 +547,27 @@ namespace {
547547// Main Logging Interface Implementation
548548// -----------------------------------------------------------------------------
549549
550+ // Internal helper for cleanup (no locking to avoid deadlock with stream capture).
551+ static void ShutdownUnlocked () {
552+ // Restore original stream buffers
553+ if (g_orig_cout) {
554+ std::cout.rdbuf (g_orig_cout);
555+ }
556+ if (g_orig_cerr) {
557+ std::cerr.rdbuf (g_orig_cerr);
558+ }
559+ g_cout_capture.reset ();
560+ g_cerr_capture.reset ();
561+
562+ g_cli_logger.reset ();
563+ g_backend.reset ();
564+ g_initialized = false ;
565+ }
566+
550567bool Initialize (const LoggingConfig& config) {
551- std::lock_guard<std::mutex> lock (g_logging_mutex);
552-
553568 // Shutdown existing logging if any
554569 if (g_initialized) {
555- Shutdown ();
570+ ShutdownUnlocked ();
556571 }
557572
558573 g_backend = std::make_shared<LoggerBackend>(config);
@@ -572,36 +587,25 @@ bool Initialize(const LoggingConfig& config) {
572587 std::cout.rdbuf (g_cout_capture.get ());
573588 std::cerr.rdbuf (g_cerr_capture.get ());
574589 // Ensure restoration happens even if user code forgets to call Shutdown.
575- std::atexit ([](){ Shutdown (); });
590+ // Note: Only register once to avoid multiple atexit handlers
591+ static bool atexit_registered = false ;
592+ if (!atexit_registered) {
593+ std::atexit ([](){ Shutdown (); });
594+ atexit_registered = true ;
595+ }
576596 g_initialized = true ;
577597 return true ;
578598}
579599
580600void Shutdown () {
581- std::lock_guard<std::mutex> lock (g_logging_mutex);
582-
583- // Restore original stream buffers
584- if (g_orig_cout) {
585- std::cout.rdbuf (g_orig_cout);
586- }
587- if (g_orig_cerr) {
588- std::cerr.rdbuf (g_orig_cerr);
589- }
590- g_cout_capture.reset ();
591- g_cerr_capture.reset ();
592-
593- g_cli_logger.reset ();
594- g_backend.reset ();
595- g_initialized = false ;
601+ ShutdownUnlocked ();
596602}
597603
598604static std::shared_ptr<CLILogger> GetCLILogger () {
599- std::lock_guard<std::mutex> lock (g_logging_mutex);
600605 return g_cli_logger;
601606}
602607
603608bool IsInitialized () noexcept {
604- std::lock_guard<std::mutex> lock (g_logging_mutex);
605609 return g_initialized && g_backend != nullptr ;
606610}
607611
@@ -788,7 +792,6 @@ void LogError(const std::string& message) {
788792}
789793
790794bool IsDebugEnabled () noexcept {
791- std::lock_guard<std::mutex> lock (g_logging_mutex);
792795 if (!g_initialized || !g_backend) return false ;
793796 const auto & cfg = g_backend->GetConfig ();
794797 // Enable if explicitly requested or if either sink is set to Debug threshold
0 commit comments