Move TsCerr to separate header.
This commit is contained in:
parent
674a112bfa
commit
df4c4b9471
@ -12,6 +12,7 @@
|
|||||||
#include "td/utils/filesystem.h"
|
#include "td/utils/filesystem.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
|
#include "td/utils/TsCerr.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -114,6 +114,7 @@ set(TDUTILS_SOURCE
|
|||||||
td/utils/TsFileLog.cpp
|
td/utils/TsFileLog.cpp
|
||||||
td/utils/tl_parsers.cpp
|
td/utils/tl_parsers.cpp
|
||||||
td/utils/translit.cpp
|
td/utils/translit.cpp
|
||||||
|
td/utils/TsCerr.cpp
|
||||||
td/utils/TsFileLog.cpp
|
td/utils/TsFileLog.cpp
|
||||||
td/utils/unicode.cpp
|
td/utils/unicode.cpp
|
||||||
td/utils/utf8.cpp
|
td/utils/utf8.cpp
|
||||||
@ -257,6 +258,7 @@ set(TDUTILS_SOURCE
|
|||||||
td/utils/tl_parsers.h
|
td/utils/tl_parsers.h
|
||||||
td/utils/tl_storers.h
|
td/utils/tl_storers.h
|
||||||
td/utils/translit.h
|
td/utils/translit.h
|
||||||
|
td/utils/TsCerr.h
|
||||||
td/utils/TsFileLog.h
|
td/utils/TsFileLog.h
|
||||||
td/utils/TsList.h
|
td/utils/TsList.h
|
||||||
td/utils/type_traits.h
|
td/utils/type_traits.h
|
||||||
|
64
tdutils/td/utils/TsCerr.cpp
Normal file
64
tdutils/td/utils/TsCerr.cpp
Normal file
@ -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
|
33
tdutils/td/utils/TsCerr.h
Normal file
33
tdutils/td/utils/TsCerr.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "td/utils/Slice.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace td {
|
||||||
|
|
||||||
|
class TsCerr {
|
||||||
|
public:
|
||||||
|
TsCerr();
|
||||||
|
TsCerr(const TsCerr &) = delete;
|
||||||
|
TsCerr &operator=(const TsCerr &) = delete;
|
||||||
|
TsCerr(TsCerr &&) = delete;
|
||||||
|
TsCerr &operator=(TsCerr &&) = delete;
|
||||||
|
~TsCerr();
|
||||||
|
|
||||||
|
TsCerr &operator<<(Slice slice);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::atomic_flag lock_;
|
||||||
|
|
||||||
|
void enterCritical();
|
||||||
|
void exitCritical();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace td
|
@ -8,10 +8,9 @@
|
|||||||
|
|
||||||
#include "td/utils/ExitGuard.h"
|
#include "td/utils/ExitGuard.h"
|
||||||
#include "td/utils/port/Clocks.h"
|
#include "td/utils/port/Clocks.h"
|
||||||
#include "td/utils/port/StdStreams.h"
|
|
||||||
#include "td/utils/port/thread_local.h"
|
#include "td/utils/port/thread_local.h"
|
||||||
#include "td/utils/Slice.h"
|
#include "td/utils/Slice.h"
|
||||||
#include "td/utils/Time.h"
|
#include "td/utils/TsCerr.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -151,54 +150,6 @@ Logger::~Logger() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
TsCerr::Lock TsCerr::lock_ = ATOMIC_FLAG_INIT;
|
|
||||||
|
|
||||||
void TsLog::enter_critical() {
|
|
||||||
while (lock_.test_and_set(std::memory_order_acquire) && !ExitGuard::is_exited()) {
|
|
||||||
// spin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TsLog::exit_critical() {
|
void TsLog::exit_critical() {
|
||||||
lock_.clear(std::memory_order_release);
|
lock_.clear(std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
@ -185,24 +185,6 @@ extern LogInterface *log_interface;
|
|||||||
using OnLogMessageCallback = void (*)(int verbosity_level, CSlice message);
|
using OnLogMessageCallback = void (*)(int verbosity_level, CSlice message);
|
||||||
void set_log_message_callback(int max_verbosity_level, OnLogMessageCallback callback);
|
void set_log_message_callback(int max_verbosity_level, OnLogMessageCallback callback);
|
||||||
|
|
||||||
class TsCerr {
|
|
||||||
public:
|
|
||||||
TsCerr();
|
|
||||||
TsCerr(const TsCerr &) = delete;
|
|
||||||
TsCerr &operator=(const TsCerr &) = delete;
|
|
||||||
TsCerr(TsCerr &&) = delete;
|
|
||||||
TsCerr &operator=(TsCerr &&) = delete;
|
|
||||||
~TsCerr();
|
|
||||||
TsCerr &operator<<(Slice slice);
|
|
||||||
|
|
||||||
private:
|
|
||||||
using Lock = std::atomic_flag;
|
|
||||||
static Lock lock_;
|
|
||||||
|
|
||||||
void enterCritical();
|
|
||||||
void exitCritical();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Logger {
|
class Logger {
|
||||||
static const size_t BUFFER_SIZE = 128 * 1024;
|
static const size_t BUFFER_SIZE = 128 * 1024;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user