sharkdp / dbg-macro

A dbg(…) macro for C++

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multi-threaded support

mikelui opened this issue · comments

Is there any effort to create a thread-safe version?

From a cursory glance, it looks like it would require some thread_local specifiers and locking the error stream.

EDIT: My cursory glance was too cursory. I thought I spotted some namespace scoped variables.

There is no effort so far, but I'd certainly be in favor of adding support (unless this would somehow require an insane amount of code). Thank you for the feedback!

The dbg macro and the associated structs and functions have no shared state, so they can't race. The std::cerr stream is also thread-safe, so in principle it should suffice to chain all writes to std::cerr together.

diff --git a/dbg.h b/dbg.h
index da26989..55d243e 100644
--- a/dbg.h
+++ b/dbg.h
@@ -319,17 +319,19 @@ class DebugOutput {
     std::stringstream stream_value;
     const bool print_expr_and_type = pretty_print(stream_value, ref);
 
-    std::cerr << ansi(ANSI_DEBUG) << "[" << m_filepath << ":" << m_line << " ("
+    std::stringstream output;
+    output << ansi(ANSI_DEBUG) << "[" << m_filepath << ":" << m_line << " ("
               << m_function_name << ")] " << ansi(ANSI_RESET);
     if (print_expr_and_type) {
-      std::cerr << ansi(ANSI_EXPRESSION) << m_expression << ansi(ANSI_RESET)
+      output << ansi(ANSI_EXPRESSION) << m_expression << ansi(ANSI_RESET)
                 << " = ";
     }
-    std::cerr << ansi(ANSI_VALUE) << stream_value.str() << ansi(ANSI_RESET);
+    output << ansi(ANSI_VALUE) << stream_value.str() << ansi(ANSI_RESET);
     if (print_expr_and_type) {
-      std::cerr << " (" << ansi(ANSI_TYPE) << type << ansi(ANSI_RESET) << ")";
+      output << " (" << ansi(ANSI_TYPE) << type << ansi(ANSI_RESET) << ")";
     }
-    std::cerr << std::endl;
+    output << std::endl;
+    std::cerr << output.str();
 
     return std::forward<T>(value);
   }

Of course the << ostream operator must be thread-safe for the value to be streamed, but that is the user's responsibility. A well-behaved << operators should be const anyway.

Thank you for the analysis! I think it is spot on. Let's implement the change with the additional stringstream 👍

If the master branch hasn't diverged too far since my comment, you can just git apply the patch.

Thank you.