tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

globals.cc (5431B)


      1 // Copyright 2022 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "absl/log/globals.h"
     16 
     17 #include <atomic>
     18 #include <cstddef>
     19 #include <cstdint>
     20 #include <cstdlib>
     21 #include <cstring>
     22 #include <string>
     23 
     24 #include "absl/base/attributes.h"
     25 #include "absl/base/config.h"
     26 #include "absl/base/internal/atomic_hook.h"
     27 #include "absl/base/internal/raw_logging.h"
     28 #include "absl/base/log_severity.h"
     29 #include "absl/hash/hash.h"
     30 #include "absl/strings/string_view.h"
     31 
     32 namespace absl {
     33 ABSL_NAMESPACE_BEGIN
     34 namespace {
     35 
     36 // These atomics represent logging library configuration.
     37 // Integer types are used instead of absl::LogSeverity to ensure that a
     38 // lock-free std::atomic is used when possible.
     39 ABSL_CONST_INIT std::atomic<int> min_log_level{
     40    static_cast<int>(absl::LogSeverityAtLeast::kInfo)};
     41 ABSL_CONST_INIT std::atomic<int> stderrthreshold{
     42    static_cast<int>(absl::LogSeverityAtLeast::kError)};
     43 // We evaluate this value as a hash comparison to avoid having to
     44 // hold a mutex or make a copy (to access the value of a string-typed flag) in
     45 // very hot codepath.
     46 ABSL_CONST_INIT std::atomic<size_t> log_backtrace_at_hash{0};
     47 ABSL_CONST_INIT std::atomic<bool> prepend_log_prefix{true};
     48 
     49 constexpr char kDefaultAndroidTag[] = "native";
     50 ABSL_CONST_INIT std::atomic<const char*> android_log_tag{kDefaultAndroidTag};
     51 
     52 ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
     53 absl::base_internal::AtomicHook<log_internal::LoggingGlobalsListener>
     54    logging_globals_listener;
     55 
     56 size_t HashSiteForLogBacktraceAt(absl::string_view file, int line) {
     57  return absl::HashOf(file, line);
     58 }
     59 
     60 void TriggerLoggingGlobalsListener() {
     61  auto* listener = logging_globals_listener.Load();
     62  if (listener != nullptr) listener();
     63 }
     64 
     65 }  // namespace
     66 
     67 namespace log_internal {
     68 
     69 void RawSetMinLogLevel(absl::LogSeverityAtLeast severity) {
     70  min_log_level.store(static_cast<int>(severity), std::memory_order_release);
     71 }
     72 
     73 void RawSetStderrThreshold(absl::LogSeverityAtLeast severity) {
     74  stderrthreshold.store(static_cast<int>(severity), std::memory_order_release);
     75 }
     76 
     77 void RawEnableLogPrefix(bool on_off) {
     78  prepend_log_prefix.store(on_off, std::memory_order_release);
     79 }
     80 
     81 void SetLoggingGlobalsListener(LoggingGlobalsListener l) {
     82  logging_globals_listener.Store(l);
     83 }
     84 
     85 }  // namespace log_internal
     86 
     87 absl::LogSeverityAtLeast MinLogLevel() {
     88  return static_cast<absl::LogSeverityAtLeast>(
     89      min_log_level.load(std::memory_order_acquire));
     90 }
     91 
     92 void SetMinLogLevel(absl::LogSeverityAtLeast severity) {
     93  log_internal::RawSetMinLogLevel(severity);
     94  TriggerLoggingGlobalsListener();
     95 }
     96 
     97 namespace log_internal {
     98 
     99 ScopedMinLogLevel::ScopedMinLogLevel(absl::LogSeverityAtLeast severity)
    100    : saved_severity_(absl::MinLogLevel()) {
    101  absl::SetMinLogLevel(severity);
    102 }
    103 ScopedMinLogLevel::~ScopedMinLogLevel() {
    104  absl::SetMinLogLevel(saved_severity_);
    105 }
    106 
    107 }  // namespace log_internal
    108 
    109 absl::LogSeverityAtLeast StderrThreshold() {
    110  return static_cast<absl::LogSeverityAtLeast>(
    111      stderrthreshold.load(std::memory_order_acquire));
    112 }
    113 
    114 void SetStderrThreshold(absl::LogSeverityAtLeast severity) {
    115  log_internal::RawSetStderrThreshold(severity);
    116  TriggerLoggingGlobalsListener();
    117 }
    118 
    119 ScopedStderrThreshold::ScopedStderrThreshold(absl::LogSeverityAtLeast severity)
    120    : saved_severity_(absl::StderrThreshold()) {
    121  absl::SetStderrThreshold(severity);
    122 }
    123 
    124 ScopedStderrThreshold::~ScopedStderrThreshold() {
    125  absl::SetStderrThreshold(saved_severity_);
    126 }
    127 
    128 namespace log_internal {
    129 
    130 const char* GetAndroidNativeTag() {
    131  return android_log_tag.load(std::memory_order_acquire);
    132 }
    133 
    134 }  // namespace log_internal
    135 
    136 void SetAndroidNativeTag(const char* tag) {
    137  ABSL_CONST_INIT static std::atomic<const std::string*> user_log_tag(nullptr);
    138  ABSL_INTERNAL_CHECK(tag, "tag must be non-null.");
    139 
    140  const std::string* tag_str = new std::string(tag);
    141  ABSL_INTERNAL_CHECK(
    142      android_log_tag.exchange(tag_str->c_str(), std::memory_order_acq_rel) ==
    143          kDefaultAndroidTag,
    144      "SetAndroidNativeTag() must only be called once per process!");
    145  user_log_tag.store(tag_str, std::memory_order_relaxed);
    146 }
    147 
    148 namespace log_internal {
    149 
    150 bool ShouldLogBacktraceAt(absl::string_view file, int line) {
    151  const size_t flag_hash =
    152      log_backtrace_at_hash.load(std::memory_order_relaxed);
    153 
    154  return flag_hash != 0 && flag_hash == HashSiteForLogBacktraceAt(file, line);
    155 }
    156 
    157 }  // namespace log_internal
    158 
    159 void SetLogBacktraceLocation(absl::string_view file, int line) {
    160  log_backtrace_at_hash.store(HashSiteForLogBacktraceAt(file, line),
    161                              std::memory_order_relaxed);
    162 }
    163 
    164 void ClearLogBacktraceLocation() {
    165  log_backtrace_at_hash.store(0, std::memory_order_relaxed);
    166 }
    167 
    168 bool ShouldPrependLogPrefix() {
    169  return prepend_log_prefix.load(std::memory_order_acquire);
    170 }
    171 
    172 void EnableLogPrefix(bool on_off) {
    173  log_internal::RawEnableLogPrefix(on_off);
    174  TriggerLoggingGlobalsListener();
    175 }
    176 
    177 ABSL_NAMESPACE_END
    178 }  // namespace absl