aboutsummaryrefslogtreecommitdiffhomepage
path: root/tdutils/td/utils/TsCerr.cpp
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2021-05-18 17:24:32 +0300
committerlevlam <levlam@telegram.org>2021-05-18 17:24:32 +0300
commitdf4c4b94714ca8aaecb3afb87e67a55b5203ca47 (patch)
treef7ac9626a0082d6a0be929ebd61fdae1494aaae6 /tdutils/td/utils/TsCerr.cpp
parent674a112bfa7d19cd68bccc43b1fcc458a9e5bf8c (diff)
Move TsCerr to separate header.
Diffstat (limited to 'tdutils/td/utils/TsCerr.cpp')
-rw-r--r--tdutils/td/utils/TsCerr.cpp64
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