Commit cbdbec09 by Abseil Team Committed by Copybara-Service

Use absl::NoDestructor for cordz global queue.

Also updated the return value to reference to clarify non-nullability.

PiperOrigin-RevId: 602730828
Change-Id: Ia36f7fde3cc87ac597ba4f194eebe9ebb90a1a09
parent 04af270f
...@@ -614,8 +614,8 @@ cc_library( ...@@ -614,8 +614,8 @@ cc_library(
"//absl:__subpackages__", "//absl:__subpackages__",
], ],
deps = [ deps = [
"//absl/base",
"//absl/base:config", "//absl/base:config",
"//absl/base:no_destructor",
"//absl/base:raw_logging_internal", "//absl/base:raw_logging_internal",
"//absl/synchronization", "//absl/synchronization",
], ],
......
...@@ -799,6 +799,7 @@ absl_cc_library( ...@@ -799,6 +799,7 @@ absl_cc_library(
DEPS DEPS
absl::base absl::base
absl::config absl::config
absl::no_destructor
absl::raw_logging_internal absl::raw_logging_internal
absl::synchronization absl::synchronization
) )
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <atomic> #include <atomic>
#include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK #include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK
#include "absl/base/no_destructor.h"
#include "absl/synchronization/mutex.h" #include "absl/synchronization/mutex.h"
namespace absl { namespace absl {
...@@ -43,33 +44,32 @@ struct Queue { ...@@ -43,33 +44,32 @@ struct Queue {
} }
}; };
static Queue* GlobalQueue() { static Queue& GlobalQueue() {
static Queue* global_queue = new Queue; static absl::NoDestructor<Queue> global_queue;
return global_queue; return *global_queue;
} }
} // namespace } // namespace
CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) {
Queue* global_queue = GlobalQueue(); Queue& global_queue = GlobalQueue();
if (is_snapshot) { if (is_snapshot) {
MutexLock lock(&global_queue->mutex); MutexLock lock(&global_queue.mutex);
CordzHandle* dq_tail = CordzHandle* dq_tail = global_queue.dq_tail.load(std::memory_order_acquire);
global_queue->dq_tail.load(std::memory_order_acquire);
if (dq_tail != nullptr) { if (dq_tail != nullptr) {
dq_prev_ = dq_tail; dq_prev_ = dq_tail;
dq_tail->dq_next_ = this; dq_tail->dq_next_ = this;
} }
global_queue->dq_tail.store(this, std::memory_order_release); global_queue.dq_tail.store(this, std::memory_order_release);
} }
} }
CordzHandle::~CordzHandle() { CordzHandle::~CordzHandle() {
Queue* global_queue = GlobalQueue(); Queue& global_queue = GlobalQueue();
if (is_snapshot_) { if (is_snapshot_) {
std::vector<CordzHandle*> to_delete; std::vector<CordzHandle*> to_delete;
{ {
MutexLock lock(&global_queue->mutex); MutexLock lock(&global_queue.mutex);
CordzHandle* next = dq_next_; CordzHandle* next = dq_next_;
if (dq_prev_ == nullptr) { if (dq_prev_ == nullptr) {
// We were head of the queue, delete every CordzHandle until we reach // We were head of the queue, delete every CordzHandle until we reach
...@@ -85,7 +85,7 @@ CordzHandle::~CordzHandle() { ...@@ -85,7 +85,7 @@ CordzHandle::~CordzHandle() {
if (next) { if (next) {
next->dq_prev_ = dq_prev_; next->dq_prev_ = dq_prev_;
} else { } else {
global_queue->dq_tail.store(dq_prev_, std::memory_order_release); global_queue.dq_tail.store(dq_prev_, std::memory_order_release);
} }
} }
for (CordzHandle* handle : to_delete) { for (CordzHandle* handle : to_delete) {
...@@ -95,20 +95,20 @@ CordzHandle::~CordzHandle() { ...@@ -95,20 +95,20 @@ CordzHandle::~CordzHandle() {
} }
bool CordzHandle::SafeToDelete() const { bool CordzHandle::SafeToDelete() const {
return is_snapshot_ || GlobalQueue()->IsEmpty(); return is_snapshot_ || GlobalQueue().IsEmpty();
} }
void CordzHandle::Delete(CordzHandle* handle) { void CordzHandle::Delete(CordzHandle* handle) {
assert(handle); assert(handle);
if (handle) { if (handle) {
Queue* const queue = GlobalQueue(); Queue& queue = GlobalQueue();
if (!handle->SafeToDelete()) { if (!handle->SafeToDelete()) {
MutexLock lock(&queue->mutex); MutexLock lock(&queue.mutex);
CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire); CordzHandle* dq_tail = queue.dq_tail.load(std::memory_order_acquire);
if (dq_tail != nullptr) { if (dq_tail != nullptr) {
handle->dq_prev_ = dq_tail; handle->dq_prev_ = dq_tail;
dq_tail->dq_next_ = handle; dq_tail->dq_next_ = handle;
queue->dq_tail.store(handle, std::memory_order_release); queue.dq_tail.store(handle, std::memory_order_release);
return; return;
} }
} }
...@@ -118,9 +118,9 @@ void CordzHandle::Delete(CordzHandle* handle) { ...@@ -118,9 +118,9 @@ void CordzHandle::Delete(CordzHandle* handle) {
std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() {
std::vector<const CordzHandle*> handles; std::vector<const CordzHandle*> handles;
Queue* global_queue = GlobalQueue(); Queue& global_queue = GlobalQueue();
MutexLock lock(&global_queue->mutex); MutexLock lock(&global_queue.mutex);
CordzHandle* dq_tail = global_queue->dq_tail.load(std::memory_order_acquire); CordzHandle* dq_tail = global_queue.dq_tail.load(std::memory_order_acquire);
for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) {
handles.push_back(p); handles.push_back(p);
} }
...@@ -133,9 +133,9 @@ bool CordzHandle::DiagnosticsHandleIsSafeToInspect( ...@@ -133,9 +133,9 @@ bool CordzHandle::DiagnosticsHandleIsSafeToInspect(
if (handle == nullptr) return true; if (handle == nullptr) return true;
if (handle->is_snapshot_) return false; if (handle->is_snapshot_) return false;
bool snapshot_found = false; bool snapshot_found = false;
Queue* global_queue = GlobalQueue(); Queue& global_queue = GlobalQueue();
MutexLock lock(&global_queue->mutex); MutexLock lock(&global_queue.mutex);
for (const CordzHandle* p = global_queue->dq_tail; p; p = p->dq_prev_) { for (const CordzHandle* p = global_queue.dq_tail; p; p = p->dq_prev_) {
if (p == handle) return !snapshot_found; if (p == handle) return !snapshot_found;
if (p == this) snapshot_found = true; if (p == this) snapshot_found = true;
} }
...@@ -150,8 +150,8 @@ CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() { ...@@ -150,8 +150,8 @@ CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() {
return handles; return handles;
} }
Queue* global_queue = GlobalQueue(); Queue& global_queue = GlobalQueue();
MutexLock lock(&global_queue->mutex); MutexLock lock(&global_queue.mutex);
for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) {
if (!p->is_snapshot()) { if (!p->is_snapshot()) {
handles.push_back(p); handles.push_back(p);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment