diff options
Diffstat (limited to 'libbutl/diagnostics.cxx')
-rw-r--r-- | libbutl/diagnostics.cxx | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/libbutl/diagnostics.cxx b/libbutl/diagnostics.cxx index 8525d60..6ac8192 100644 --- a/libbutl/diagnostics.cxx +++ b/libbutl/diagnostics.cxx @@ -17,6 +17,14 @@ #include <cstddef> // size_t #include <iostream> // cerr +#ifndef LIBBUTL_MINGW_STDTHREAD +# include <mutex> +#else +# include <libbutl/mingw-mutex.hxx> +#endif + +#include <libbutl/ft/lang.hxx> // thread_local + #include <libbutl/utility.hxx> #include <libbutl/optional.hxx> #include <libbutl/fdstream.hxx> @@ -27,7 +35,11 @@ namespace butl { ostream* diag_stream = &cerr; - static mutex diag_mutex; +#ifndef LIBBUTL_MINGW_STDTHREAD + static std::mutex diag_mutex; +#else + static mingw_stdthread::mutex diag_mutex; +#endif string diag_progress; static string diag_progress_blank; // Being printed blanks out the line. @@ -131,28 +143,28 @@ namespace butl default_writer (const diag_record& r) { r.os.put ('\n'); - diag_stream_lock () << r.os.str (); + + diag_stream_lock l; + (*diag_stream) << r.os.str (); // We can endup flushing the result of several writes. The last one may // possibly be incomplete, but that's not a problem as it will also be // followed by the flush() call. // - // @@ Strange: why not just hold the lock for both write and flush? - // diag_stream->flush (); } - void (*diag_record::writer) (const diag_record&) = &default_writer; + diag_writer* diag_record::writer = &default_writer; void diag_record:: - flush () const + flush (void (*w) (const diag_record&)) const { if (!empty_) { if (epilogue_ == nullptr) { - if (writer != nullptr) - writer (*this); + if (w != nullptr || (w = writer) != nullptr) + w (*this); empty_ = true; } @@ -162,8 +174,8 @@ namespace butl // auto e (epilogue_); epilogue_ = nullptr; - e (*this); // Can throw. - flush (); // Call ourselves to write the data in case it returns. + e (*this, w); // Can throw. + flush (w); // Call ourselves to write the data in case it returns. } } } @@ -186,4 +198,28 @@ namespace butl flush (); #endif } + + // Diagnostics stack. + // + static +#ifdef __cpp_thread_local + thread_local +#else + __thread +#endif + const diag_frame* diag_frame_stack = nullptr; + + const diag_frame* diag_frame:: + stack () noexcept + { + return diag_frame_stack; + } + + const diag_frame* diag_frame:: + stack (const diag_frame* f) noexcept + { + const diag_frame* r (diag_frame_stack); + diag_frame_stack = f; + return r; + } } |