diff options
| author | levlam <levlam@telegram.org> | 2021-05-18 17:24:32 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2021-05-18 17:24:32 +0300 |
| commit | df4c4b94714ca8aaecb3afb87e67a55b5203ca47 (patch) | |
| tree | f7ac9626a0082d6a0be929ebd61fdae1494aaae6 /tdutils/td/utils/TsCerr.cpp | |
| parent | 674a112bfa7d19cd68bccc43b1fcc458a9e5bf8c (diff) | |
Move TsCerr to separate header.
Diffstat (limited to 'tdutils/td/utils/TsCerr.cpp')
| -rw-r--r-- | tdutils/td/utils/TsCerr.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/tdutils/td/utils/TsCerr.cpp b/tdutils/td/utils/TsCerr.cpp new file mode 100644 index 000000000..3ef759a13 --- /dev/null +++ b/tdutils/td/utils/TsCerr.cpp @@ -0,0 +1,64 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/utils/TsCerr.h" + +#include "td/utils/ExitGuard.h" +#include "td/utils/port/StdStreams.h" +#include "td/utils/Time.h" + +#include <cerrno> + +namespace td { + +std::atomic_flag TsCerr::lock_ = ATOMIC_FLAG_INIT; + +TsCerr::TsCerr() { + enterCritical(); +} + +TsCerr::~TsCerr() { + exitCritical(); +} + +TsCerr &TsCerr::operator<<(Slice slice) { + auto &fd = Stderr(); + if (fd.empty()) { + return *this; + } + double end_time = 0; + while (!slice.empty()) { + auto res = fd.write(slice); + if (res.is_error()) { + if (res.error().code() == EPIPE) { + break; + } + // Resource temporary unavailable + if (end_time == 0) { + end_time = Time::now() + 0.01; + } else if (Time::now() > end_time) { + break; + } + continue; + } + slice.remove_prefix(res.ok()); + } + return *this; +} + +void TsCerr::enterCritical() { + while (lock_.test_and_set(std::memory_order_acquire) && !ExitGuard::is_exited()) { + // spin + } +} + +void TsCerr::exitCritical() { + lock_.clear(std::memory_order_release); +} + +static ExitGuard exit_guard; + +} // namespace td |
