aboutsummaryrefslogtreecommitdiff
path: root/libbutl/diagnostics.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbutl/diagnostics.cxx')
-rw-r--r--libbutl/diagnostics.cxx89
1 files changed, 49 insertions, 40 deletions
diff --git a/libbutl/diagnostics.cxx b/libbutl/diagnostics.cxx
index b038e5d..6ac8192 100644
--- a/libbutl/diagnostics.cxx
+++ b/libbutl/diagnostics.cxx
@@ -1,9 +1,7 @@
// file : libbutl/diagnostics.cxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
-#ifndef __cpp_modules_ts
-#include <libbutl/diagnostics.mxx>
-#endif
+#include <libbutl/diagnostics.hxx>
#ifndef _WIN32
# include <unistd.h> // write()
@@ -12,49 +10,36 @@
# include <io.h> //_write()
#endif
-#include <cassert>
-
-#ifndef __cpp_lib_modules_ts
-#include <utility>
-#include <exception>
-
#include <ios> // ios::failure
#include <mutex>
#include <string>
+#include <cassert>
#include <cstddef> // size_t
#include <iostream> // cerr
-#endif
-
-// Other includes.
-#ifdef __cpp_modules_ts
-module butl.diagnostics;
-
-// Only imports additional to interface.
-#ifdef __clang__
-#ifdef __cpp_lib_modules_ts
-import std.core;
-import std.io;
-#endif
-#endif
-
-import std.threading;
-import butl.utility;
-import butl.optional;
-import butl.fdstream; // stderr_fd(), fdterm()
+#ifndef LIBBUTL_MINGW_STDTHREAD
+# include <mutex>
#else
-#include <libbutl/utility.mxx>
-#include <libbutl/optional.mxx>
-#include <libbutl/fdstream.mxx>
+# 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>
+
using namespace std;
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.
@@ -158,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;
}
@@ -189,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.
}
}
}
@@ -213,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;
+ }
}