YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/gutil/ref_counted.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
//
5
// The following only applies to changes made to this file as part of YugaByte development.
6
//
7
// Portions Copyright (c) YugaByte, Inc.
8
//
9
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
10
// in compliance with the License.  You may obtain a copy of the License at
11
//
12
// http://www.apache.org/licenses/LICENSE-2.0
13
//
14
// Unless required by applicable law or agreed to in writing, software distributed under the License
15
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
16
// or implied.  See the License for the specific language governing permissions and limitations
17
// under the License.
18
//
19
20
#include "yb/gutil/ref_counted.h"
21
22
#include <atomic>
23
#include <regex>
24
25
#include <glog/logging.h>
26
27
#include "yb/gutil/threading/thread_collision_warner.h"
28
29
namespace yb {
30
31
namespace subtle {
32
33
RefCountedBase::RefCountedBase()
34
    : ref_count_(0)
35
#ifndef NDEBUG
36
    , in_dtor_(false)
37
#endif
38
0
    {
39
0
}
40
41
0
RefCountedBase::~RefCountedBase() {
42
0
#ifndef NDEBUG
43
0
  DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
44
0
#endif
45
0
}
46
47
0
void RefCountedBase::AddRef() const {
48
  // TODO(maruel): Add back once it doesn't assert 500 times/sec.
49
  // Current thread books the critical section "AddRelease" without release it.
50
  // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
51
0
#ifndef NDEBUG
52
0
  DCHECK(!in_dtor_);
53
0
#endif
54
0
  ++ref_count_;
55
0
}
56
57
0
bool RefCountedBase::Release() const {
58
  // TODO(maruel): Add back once it doesn't assert 500 times/sec.
59
  // Current thread books the critical section "AddRelease" without release it.
60
  // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
61
0
#ifndef NDEBUG
62
0
  DCHECK(!in_dtor_);
63
0
#endif
64
0
  if (--ref_count_ == 0) {
65
0
#ifndef NDEBUG
66
0
    in_dtor_ = true;
67
0
#endif
68
0
    return true;
69
0
  }
70
0
  return false;
71
0
}
72
73
132M
bool RefCountedThreadSafeBase::HasOneRef() const {
74
132M
  return ref_count_.load(std::memory_order_acquire) == 1;
75
132M
}
76
77
149M
RefCountedThreadSafeBase::~RefCountedThreadSafeBase() {
78
149M
#ifndef NDEBUG
79
18.4E
  DCHECK(in_dtor_) << "RefCountedThreadSafe object deleted without "
80
18.4E
                      "calling Release()";
81
149M
#endif
82
149M
}
83
84
1.10G
void RefCountedThreadSafeBase::AddRef() const {
85
1.10G
#ifndef NDEBUG
86
1.10G
  DCHECK(!in_dtor_);
87
1.10G
#endif
88
1.10G
  ref_count_.fetch_add(1, std::memory_order_acq_rel);
89
1.10G
}
90
91
1.05G
bool RefCountedThreadSafeBase::Release() const {
92
1.05G
#ifndef NDEBUG
93
1.05G
  DCHECK(!in_dtor_);
94
1.05G
  DCHECK_NE(ref_count_.load(std::memory_order_relaxed), 0);
95
1.05G
#endif
96
1.05G
  if (ref_count_.fetch_sub(1, std::memory_order_acq_rel) == 1) {
97
149M
#ifndef NDEBUG
98
149M
    in_dtor_ = true;
99
149M
#endif
100
149M
    return true;
101
149M
  }
102
904M
  return false;
103
904M
}
104
105
#ifndef NDEBUG
106
107
bool g_ref_counted_debug_enabled = false;
108
109
namespace {
110
111
RefCountedDebugFn* g_ref_counted_debug_report_event_fn;
112
std::regex g_ref_counted_debug_type_name_regex;
113
114
}  // anonymous namespace
115
116
void InitRefCountedDebugging(const std::string& type_name_regex,
117
17.9k
                             RefCountedDebugFn* debug_fn) {
118
17.9k
  g_ref_counted_debug_report_event_fn = debug_fn;
119
17.9k
  g_ref_counted_debug_enabled = !type_name_regex.empty();
120
17.9k
  if (g_ref_counted_debug_enabled) {
121
0
    g_ref_counted_debug_type_name_regex = std::regex(type_name_regex);
122
0
  }
123
17.9k
}
124
125
void RefCountedDebugHook(
126
    const char* type_name,
127
    const void* this_ptr,
128
    int64_t current_ref_count,
129
0
    int64_t ref_delta) {
130
0
  std::match_results<const char*> match;
131
0
  if (!std::regex_match(type_name, match, g_ref_counted_debug_type_name_regex)) {
132
0
    return;
133
0
  }
134
135
0
  (*g_ref_counted_debug_report_event_fn)(type_name, this_ptr, current_ref_count, ref_delta);
136
0
}
137
138
#else
139
140
void InitRefCountedDebugging(const std::string& type_name_regex) {
141
}
142
143
#endif
144
145
}  // namespace subtle
146
147
}  // namespace yb
148
149
#ifndef NDEBUG
150
3.99G
void ScopedRefPtrCheck(bool valid) {
151
18.4E
  CHECK(valid) << "scoped_refptr is null";
152
3.99G
}
153
#endif