diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2017-05-01 16:08:43 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2017-05-01 16:59:24 +0300 |
commit | 61377c582e0f2675baa5f5e6e30a35d1a4164b33 (patch) | |
tree | 11cdca992834d7f7f197f72856712fbcb3020e3d /libbutl/diagnostics.cxx | |
parent | 442c1a6790e52baa0c081f310d4d9e9b6f1ff638 (diff) |
Add hxx extension for headers and lib prefix for library dir
Diffstat (limited to 'libbutl/diagnostics.cxx')
-rw-r--r-- | libbutl/diagnostics.cxx | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/libbutl/diagnostics.cxx b/libbutl/diagnostics.cxx new file mode 100644 index 0000000..e73412b --- /dev/null +++ b/libbutl/diagnostics.cxx @@ -0,0 +1,80 @@ +// file : libbutl/diagnostics.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <libbutl/diagnostics.hxx> + +#include <mutex> +#include <iostream> // cerr + +using namespace std; + +namespace butl +{ + ostream* diag_stream = &cerr; + + static mutex diag_mutex; + + diag_lock::diag_lock () + { + diag_mutex.lock (); + } + + diag_lock::~diag_lock () + { + diag_mutex.unlock (); + } + + void diag_record:: + flush () const + { + if (!empty_) + { + if (epilogue_ == nullptr) + { + os.put ('\n'); + + { + diag_lock l; + *diag_stream << 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. + // + diag_stream->flush (); + + empty_ = true; + } + else + { + // Clear the epilogue in case it calls us back. + // + auto e (epilogue_); + epilogue_ = nullptr; + e (*this); // Can throw. + flush (); // Call ourselves to write the data in case it returns. + } + } + } + + diag_record:: + ~diag_record () noexcept (false) + { + // Don't flush the record if this destructor was called as part of the + // stack unwinding. + // +#ifdef __cpp_lib_uncaught_exceptions + if (uncaught_ == std::uncaught_exceptions ()) + flush (); +#else + // Fallback implementation. Right now this means we cannot use this + // mechanism in destructors, which is not a big deal, except for one + // place: exception_guard. Thus the ugly special check. + // + if (!std::uncaught_exception () || exception_unwinding_dtor ()) + flush (); +#endif + } +} |