aboutsummaryrefslogtreecommitdiff
path: root/src/core/lib/gprpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/gprpp')
-rw-r--r--src/core/lib/gprpp/debug_location.h13
-rw-r--r--src/core/lib/gprpp/directory_reader.h48
-rw-r--r--src/core/lib/gprpp/dual_ref_counted.h43
-rw-r--r--src/core/lib/gprpp/host_port.cc2
-rw-r--r--src/core/lib/gprpp/match.h2
-rw-r--r--src/core/lib/gprpp/orphanable.h27
-rw-r--r--src/core/lib/gprpp/posix/directory_reader.cc82
-rw-r--r--src/core/lib/gprpp/posix/stat.cc1
-rw-r--r--src/core/lib/gprpp/ref_counted.h85
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h97
-rw-r--r--src/core/lib/gprpp/ref_counted_string.h15
-rw-r--r--src/core/lib/gprpp/status_helper.cc4
-rw-r--r--src/core/lib/gprpp/strerror.cc2
-rw-r--r--src/core/lib/gprpp/time.cc1
-rw-r--r--src/core/lib/gprpp/uuid_v4.cc2
-rw-r--r--src/core/lib/gprpp/validation_errors.cc1
-rw-r--r--src/core/lib/gprpp/windows/directory_reader.cc81
-rw-r--r--src/core/lib/gprpp/work_serializer.cc3
-rw-r--r--src/core/lib/gprpp/xxhash_inline.h29
19 files changed, 469 insertions, 69 deletions
diff --git a/src/core/lib/gprpp/debug_location.h b/src/core/lib/gprpp/debug_location.h
index 1a29f49538..c6c9b68286 100644
--- a/src/core/lib/gprpp/debug_location.h
+++ b/src/core/lib/gprpp/debug_location.h
@@ -19,6 +19,10 @@
#ifndef GRPC_SRC_CORE_LIB_GPRPP_DEBUG_LOCATION_H
#define GRPC_SRC_CORE_LIB_GPRPP_DEBUG_LOCATION_H
+#include <grpc/support/port_platform.h>
+
+#include <utility>
+
#if defined(__has_builtin)
#if __has_builtin(__builtin_FILE)
#define GRPC_DEFAULT_FILE __builtin_FILE()
@@ -77,6 +81,15 @@ class DebugLocation {
};
#endif
+template <typename T>
+struct ValueWithDebugLocation {
+ // NOLINTNEXTLINE
+ ValueWithDebugLocation(T&& value, DebugLocation debug_location = {})
+ : value(std::forward<T>(value)), debug_location(debug_location) {}
+ T value;
+ GPR_NO_UNIQUE_ADDRESS DebugLocation debug_location;
+};
+
#define DEBUG_LOCATION ::grpc_core::DebugLocation(__FILE__, __LINE__)
} // namespace grpc_core
diff --git a/src/core/lib/gprpp/directory_reader.h b/src/core/lib/gprpp/directory_reader.h
new file mode 100644
index 0000000000..0f0bbcf0b0
--- /dev/null
+++ b/src/core/lib/gprpp/directory_reader.h
@@ -0,0 +1,48 @@
+//
+//
+// Copyright 2023 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+
+#ifndef GRPC_SRC_CORE_LIB_GPRPP_DIRECTORY_READER_H
+#define GRPC_SRC_CORE_LIB_GPRPP_DIRECTORY_READER_H
+
+#include <grpc/support/port_platform.h>
+
+#include <memory>
+
+#include "absl/functional/function_ref.h"
+#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
+
+namespace grpc_core {
+
+class DirectoryReader {
+ public:
+ virtual ~DirectoryReader() = default;
+ // Returns the name of the directory being read.
+ virtual absl::string_view Name() const = 0;
+ // Calls callback for each name in the directory except for "." and "..".
+ // Returns non-OK if there was an error reading the directory.
+ virtual absl::Status ForEach(
+ absl::FunctionRef<void(absl::string_view)> callback) = 0;
+};
+
+std::unique_ptr<DirectoryReader> MakeDirectoryReader(
+ absl::string_view filename);
+
+} // namespace grpc_core
+
+#endif // GRPC_SRC_CORE_LIB_GPRPP_DIRECTORY_READER_H \ No newline at end of file
diff --git a/src/core/lib/gprpp/dual_ref_counted.h b/src/core/lib/gprpp/dual_ref_counted.h
index 4fc6ea760d..547d1312e1 100644
--- a/src/core/lib/gprpp/dual_ref_counted.h
+++ b/src/core/lib/gprpp/dual_ref_counted.h
@@ -47,19 +47,38 @@ namespace grpc_core {
template <typename Child>
class DualRefCounted : public Orphanable {
public:
+ // Not copyable nor movable.
+ DualRefCounted(const DualRefCounted&) = delete;
+ DualRefCounted& operator=(const DualRefCounted&) = delete;
+
~DualRefCounted() override = default;
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref() {
IncrementRefCount();
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
-
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref(const DebugLocation& location,
const char* reason) {
IncrementRefCount(location, reason);
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ RefCountedPtr<Subclass> RefAsSubclass() {
+ IncrementRefCount();
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ RefCountedPtr<Subclass> RefAsSubclass(const DebugLocation& location,
+ const char* reason) {
+ IncrementRefCount(location, reason);
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+
void Unref() {
// Convert strong ref to weak ref.
const uint64_t prev_ref_pair =
@@ -120,7 +139,6 @@ class DualRefCounted : public Orphanable {
std::memory_order_acq_rel, std::memory_order_acquire));
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
-
GRPC_MUST_USE_RESULT RefCountedPtr<Child> RefIfNonZero(
const DebugLocation& location, const char* reason) {
uint64_t prev_ref_pair = refs_.load(std::memory_order_acquire);
@@ -150,13 +168,28 @@ class DualRefCounted : public Orphanable {
IncrementWeakRefCount();
return WeakRefCountedPtr<Child>(static_cast<Child*>(this));
}
-
GRPC_MUST_USE_RESULT WeakRefCountedPtr<Child> WeakRef(
const DebugLocation& location, const char* reason) {
IncrementWeakRefCount(location, reason);
return WeakRefCountedPtr<Child>(static_cast<Child*>(this));
}
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ WeakRefCountedPtr<Subclass> WeakRefAsSubclass() {
+ IncrementWeakRefCount();
+ return WeakRefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ WeakRefCountedPtr<Subclass> WeakRefAsSubclass(const DebugLocation& location,
+ const char* reason) {
+ IncrementWeakRefCount(location, reason);
+ return WeakRefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+
void WeakUnref() {
#ifndef NDEBUG
// Grab a copy of the trace flag before the atomic change, since we
@@ -207,10 +240,6 @@ class DualRefCounted : public Orphanable {
}
}
- // Not copyable nor movable.
- DualRefCounted(const DualRefCounted&) = delete;
- DualRefCounted& operator=(const DualRefCounted&) = delete;
-
protected:
// Note: Tracing is a no-op in non-debug builds.
explicit DualRefCounted(
diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc
index 4e19c39a8d..47404626f9 100644
--- a/src/core/lib/gprpp/host_port.cc
+++ b/src/core/lib/gprpp/host_port.cc
@@ -22,8 +22,6 @@
#include <stddef.h>
-#include <initializer_list>
-
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
diff --git a/src/core/lib/gprpp/match.h b/src/core/lib/gprpp/match.h
index 5b210207f3..510e653f49 100644
--- a/src/core/lib/gprpp/match.h
+++ b/src/core/lib/gprpp/match.h
@@ -17,7 +17,7 @@
#include <grpc/support/port_platform.h>
-#include <type_traits>
+#include <utility>
#include "absl/types/variant.h"
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index 86319429e5..f74cadfaf0 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -97,6 +97,33 @@ class InternallyRefCounted : public Orphanable {
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ RefCountedPtr<Subclass> RefAsSubclass() {
+ IncrementRefCount();
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ RefCountedPtr<Subclass> RefAsSubclass(const DebugLocation& location,
+ const char* reason) {
+ IncrementRefCount(location, reason);
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+
+ GRPC_MUST_USE_RESULT RefCountedPtr<Child> RefIfNonZero() {
+ return RefCountedPtr<Child>(refs_.RefIfNonZero() ? static_cast<Child*>(this)
+ : nullptr);
+ }
+ GRPC_MUST_USE_RESULT RefCountedPtr<Child> RefIfNonZero(
+ const DebugLocation& location, const char* reason) {
+ return RefCountedPtr<Child>(refs_.RefIfNonZero(location, reason)
+ ? static_cast<Child*>(this)
+ : nullptr);
+ }
+
void Unref() {
if (GPR_UNLIKELY(refs_.Unref())) {
unref_behavior_(static_cast<Child*>(this));
diff --git a/src/core/lib/gprpp/posix/directory_reader.cc b/src/core/lib/gprpp/posix/directory_reader.cc
new file mode 100644
index 0000000000..ecdf3c68c6
--- /dev/null
+++ b/src/core/lib/gprpp/posix/directory_reader.cc
@@ -0,0 +1,82 @@
+//
+//
+// Copyright 2023 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+
+#include <grpc/support/port_platform.h>
+
+#include <memory>
+
+#include "absl/functional/function_ref.h"
+#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
+
+#if defined(GPR_LINUX) || defined(GPR_ANDROID) || defined(GPR_FREEBSD) || \
+ defined(GPR_APPLE)
+
+#include <dirent.h>
+
+#include <string>
+
+#include "src/core/lib/gprpp/directory_reader.h"
+
+namespace grpc_core {
+
+namespace {
+const char kSkipEntriesSelf[] = ".";
+const char kSkipEntriesParent[] = "..";
+} // namespace
+
+class DirectoryReaderImpl : public DirectoryReader {
+ public:
+ explicit DirectoryReaderImpl(absl::string_view directory_path)
+ : directory_path_(directory_path) {}
+ absl::string_view Name() const override { return directory_path_; }
+ absl::Status ForEach(absl::FunctionRef<void(absl::string_view)>) override;
+
+ private:
+ const std::string directory_path_;
+};
+
+std::unique_ptr<DirectoryReader> MakeDirectoryReader(
+ absl::string_view filename) {
+ return std::make_unique<DirectoryReaderImpl>(filename);
+}
+
+absl::Status DirectoryReaderImpl::ForEach(
+ absl::FunctionRef<void(absl::string_view)> callback) {
+ // Open the dir for reading
+ DIR* directory = opendir(directory_path_.c_str());
+ if (directory == nullptr) {
+ return absl::InternalError("Could not read crl directory.");
+ }
+ struct dirent* directory_entry;
+ // Iterate over everything in the directory
+ while ((directory_entry = readdir(directory)) != nullptr) {
+ const absl::string_view file_name = directory_entry->d_name;
+ // Skip "." and ".."
+ if (file_name == kSkipEntriesParent || file_name == kSkipEntriesSelf) {
+ continue;
+ }
+ // Call the callback with this filename
+ callback(file_name);
+ }
+ closedir(directory);
+ return absl::OkStatus();
+}
+} // namespace grpc_core
+
+#endif // GPR_LINUX || GPR_ANDROID || GPR_FREEBSD || GPR_APPLE
diff --git a/src/core/lib/gprpp/posix/stat.cc b/src/core/lib/gprpp/posix/stat.cc
index 4212ea991d..d0a8ada998 100644
--- a/src/core/lib/gprpp/posix/stat.cc
+++ b/src/core/lib/gprpp/posix/stat.cc
@@ -21,7 +21,6 @@
// IWYU pragma: no_include <bits/struct_stat.h>
#include "absl/status/status.h"
-#include "absl/strings/string_view.h"
#ifdef GPR_POSIX_STAT
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index cdf692c5ce..9d56397fdb 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -219,7 +219,7 @@ class NonPolymorphicRefCount {
// Default behavior: Delete the object.
struct UnrefDelete {
template <typename T>
- void operator()(T* p) {
+ void operator()(T* p) const {
delete p;
}
};
@@ -231,7 +231,7 @@ struct UnrefDelete {
// later by identifying entries for which RefIfNonZero() returns null.
struct UnrefNoDelete {
template <typename T>
- void operator()(T* /*p*/) {}
+ void operator()(T* /*p*/) const {}
};
// Call the object's dtor but do not delete it. This is useful for cases
@@ -239,7 +239,7 @@ struct UnrefNoDelete {
// arena).
struct UnrefCallDtor {
template <typename T>
- void operator()(T* p) {
+ void operator()(T* p) const {
p->~T();
}
};
@@ -276,35 +276,52 @@ class RefCounted : public Impl {
public:
using RefCountedChildType = Child;
+ // Not copyable nor movable.
+ RefCounted(const RefCounted&) = delete;
+ RefCounted& operator=(const RefCounted&) = delete;
+
// Note: Depending on the Impl used, this dtor can be implicitly virtual.
~RefCounted() = default;
+ // Ref() for mutable types.
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref() {
IncrementRefCount();
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
-
GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref(const DebugLocation& location,
const char* reason) {
IncrementRefCount(location, reason);
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
- // TODO(roth): Once all of our code is converted to C++ and can use
- // RefCountedPtr<> instead of manual ref-counting, make this method
- // private, since it will only be used by RefCountedPtr<>, which is a
- // friend of this class.
- void Unref() {
- if (GPR_UNLIKELY(refs_.Unref())) {
- unref_behavior_(static_cast<Child*>(this));
- }
+ // Ref() for const types.
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> Ref() const {
+ IncrementRefCount();
+ return RefCountedPtr<const Child>(static_cast<const Child*>(this));
}
- void Unref(const DebugLocation& location, const char* reason) {
- if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
- unref_behavior_(static_cast<Child*>(this));
- }
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> Ref(
+ const DebugLocation& location, const char* reason) const {
+ IncrementRefCount(location, reason);
+ return RefCountedPtr<const Child>(static_cast<const Child*>(this));
+ }
+
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ RefCountedPtr<Subclass> RefAsSubclass() {
+ IncrementRefCount();
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
+ }
+ template <
+ typename Subclass,
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
+ RefCountedPtr<Subclass> RefAsSubclass(const DebugLocation& location,
+ const char* reason) {
+ IncrementRefCount(location, reason);
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
}
+ // RefIfNonZero() for mutable types.
GRPC_MUST_USE_RESULT RefCountedPtr<Child> RefIfNonZero() {
return RefCountedPtr<Child>(refs_.RefIfNonZero() ? static_cast<Child*>(this)
: nullptr);
@@ -316,9 +333,32 @@ class RefCounted : public Impl {
: nullptr);
}
- // Not copyable nor movable.
- RefCounted(const RefCounted&) = delete;
- RefCounted& operator=(const RefCounted&) = delete;
+ // RefIfNonZero() for const types.
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> RefIfNonZero() const {
+ return RefCountedPtr<const Child>(
+ refs_.RefIfNonZero() ? static_cast<const Child*>(this) : nullptr);
+ }
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> RefIfNonZero(
+ const DebugLocation& location, const char* reason) const {
+ return RefCountedPtr<const Child>(refs_.RefIfNonZero(location, reason)
+ ? static_cast<const Child*>(this)
+ : nullptr);
+ }
+
+ // TODO(roth): Once all of our code is converted to C++ and can use
+ // RefCountedPtr<> instead of manual ref-counting, make this method
+ // private, since it will only be used by RefCountedPtr<>, which is a
+ // friend of this class.
+ void Unref() const {
+ if (GPR_UNLIKELY(refs_.Unref())) {
+ unref_behavior_(static_cast<const Child*>(this));
+ }
+ }
+ void Unref(const DebugLocation& location, const char* reason) const {
+ if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
+ unref_behavior_(static_cast<const Child*>(this));
+ }
+ }
protected:
// Note: Tracing is a no-op on non-debug builds.
@@ -336,12 +376,13 @@ class RefCounted : public Impl {
template <typename T>
friend class RefCountedPtr;
- void IncrementRefCount() { refs_.Ref(); }
- void IncrementRefCount(const DebugLocation& location, const char* reason) {
+ void IncrementRefCount() const { refs_.Ref(); }
+ void IncrementRefCount(const DebugLocation& location,
+ const char* reason) const {
refs_.Ref(location, reason);
}
- RefCount refs_;
+ mutable RefCount refs_;
GPR_NO_UNIQUE_ADDRESS UnrefBehavior unref_behavior_;
};
diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index adcffe40f1..3da9b7de0f 100644
--- a/src/core/lib/gprpp/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -43,7 +43,8 @@ class RefCountedPtr {
RefCountedPtr(std::nullptr_t) {}
// If value is non-null, we take ownership of a ref to it.
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
explicit RefCountedPtr(Y* value) : value_(value) {}
// Move ctors.
@@ -51,7 +52,8 @@ class RefCountedPtr {
value_ = other.value_;
other.value_ = nullptr;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
// NOLINTNEXTLINE(google-explicit-constructor)
RefCountedPtr(RefCountedPtr<Y>&& other) noexcept {
value_ = static_cast<T*>(other.value_);
@@ -63,7 +65,8 @@ class RefCountedPtr {
reset(std::exchange(other.value_, nullptr));
return *this;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
RefCountedPtr& operator=(RefCountedPtr<Y>&& other) noexcept {
reset(std::exchange(other.value_, nullptr));
return *this;
@@ -74,7 +77,8 @@ class RefCountedPtr {
if (other.value_ != nullptr) other.value_->IncrementRefCount();
value_ = other.value_;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
// NOLINTNEXTLINE(google-explicit-constructor)
RefCountedPtr(const RefCountedPtr<Y>& other) {
static_assert(std::has_virtual_destructor<T>::value,
@@ -92,7 +96,8 @@ class RefCountedPtr {
reset(other.value_);
return *this;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
RefCountedPtr& operator=(const RefCountedPtr<Y>& other) {
static_assert(std::has_virtual_destructor<T>::value,
"T does not have a virtual dtor");
@@ -107,6 +112,12 @@ class RefCountedPtr {
if (value_ != nullptr) value_->Unref();
}
+ // An explicit copy method that supports ref-count tracing.
+ RefCountedPtr<T> Ref(const DebugLocation& location, const char* reason) {
+ if (value_ != nullptr) value_->IncrementRefCount(location, reason);
+ return RefCountedPtr<T>(value_);
+ }
+
void swap(RefCountedPtr& other) { std::swap(value_, other.value_); }
// If value is non-null, we take ownership of a ref to it.
@@ -119,13 +130,15 @@ class RefCountedPtr {
T* old_value = std::exchange(value_, value);
if (old_value != nullptr) old_value->Unref(location, reason);
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
void reset(Y* value = nullptr) {
static_assert(std::has_virtual_destructor<T>::value,
"T does not have a virtual dtor");
reset(static_cast<T*>(value));
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
void reset(const DebugLocation& location, const char* reason,
Y* value = nullptr) {
static_assert(std::has_virtual_destructor<T>::value,
@@ -143,24 +156,34 @@ class RefCountedPtr {
T& operator*() const { return *value_; }
T* operator->() const { return value_; }
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_base_of<T, Y>::value, bool> = true>
+ RefCountedPtr<Y> TakeAsSubclass() {
+ return RefCountedPtr<Y>(static_cast<Y*>(release()));
+ }
+
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator==(const RefCountedPtr<Y>& other) const {
return value_ == other.value_;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator==(const Y* other) const {
return value_ == other;
}
bool operator==(std::nullptr_t) const { return value_ == nullptr; }
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator!=(const RefCountedPtr<Y>& other) const {
return value_ != other.value_;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator!=(const Y* other) const {
return value_ != other;
}
@@ -184,7 +207,8 @@ class WeakRefCountedPtr {
WeakRefCountedPtr(std::nullptr_t) {}
// If value is non-null, we take ownership of a ref to it.
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
explicit WeakRefCountedPtr(Y* value) {
value_ = value;
}
@@ -194,7 +218,8 @@ class WeakRefCountedPtr {
value_ = other.value_;
other.value_ = nullptr;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
// NOLINTNEXTLINE(google-explicit-constructor)
WeakRefCountedPtr(WeakRefCountedPtr<Y>&& other) noexcept {
value_ = static_cast<T*>(other.value_);
@@ -206,7 +231,8 @@ class WeakRefCountedPtr {
reset(std::exchange(other.value_, nullptr));
return *this;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
WeakRefCountedPtr& operator=(WeakRefCountedPtr<Y>&& other) noexcept {
reset(std::exchange(other.value_, nullptr));
return *this;
@@ -217,7 +243,8 @@ class WeakRefCountedPtr {
if (other.value_ != nullptr) other.value_->IncrementWeakRefCount();
value_ = other.value_;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
// NOLINTNEXTLINE(google-explicit-constructor)
WeakRefCountedPtr(const WeakRefCountedPtr<Y>& other) {
static_assert(std::has_virtual_destructor<T>::value,
@@ -235,7 +262,8 @@ class WeakRefCountedPtr {
reset(other.value_);
return *this;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
WeakRefCountedPtr& operator=(const WeakRefCountedPtr<Y>& other) {
static_assert(std::has_virtual_destructor<T>::value,
"T does not have a virtual dtor");
@@ -250,6 +278,13 @@ class WeakRefCountedPtr {
if (value_ != nullptr) value_->WeakUnref();
}
+ // An explicit copy method that supports ref-count tracing.
+ WeakRefCountedPtr<T> WeakRef(const DebugLocation& location,
+ const char* reason) {
+ if (value_ != nullptr) value_->IncrementWeakRefCount(location, reason);
+ return WeakRefCountedPtr<T>(value_);
+ }
+
void swap(WeakRefCountedPtr& other) { std::swap(value_, other.value_); }
// If value is non-null, we take ownership of a ref to it.
@@ -262,13 +297,15 @@ class WeakRefCountedPtr {
T* old_value = std::exchange(value_, value);
if (old_value != nullptr) old_value->WeakUnref(location, reason);
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
void reset(Y* value = nullptr) {
static_assert(std::has_virtual_destructor<T>::value,
"T does not have a virtual dtor");
reset(static_cast<T*>(value));
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
void reset(const DebugLocation& location, const char* reason,
Y* value = nullptr) {
static_assert(std::has_virtual_destructor<T>::value,
@@ -280,35 +317,41 @@ class WeakRefCountedPtr {
// us to pass a ref to idiomatic C code that does not use WeakRefCountedPtr<>.
// Once all of our code has been converted to idiomatic C++, this
// method should go away.
- T* release() {
- T* value = value_;
- value_ = nullptr;
- return value;
- }
+ T* release() { return std::exchange(value_, nullptr); }
T* get() const { return value_; }
T& operator*() const { return *value_; }
T* operator->() const { return value_; }
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_base_of<T, Y>::value, bool> = true>
+ WeakRefCountedPtr<Y> TakeAsSubclass() {
+ return WeakRefCountedPtr<Y>(static_cast<Y*>(release()));
+ }
+
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator==(const WeakRefCountedPtr<Y>& other) const {
return value_ == other.value_;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator==(const Y* other) const {
return value_ == other;
}
bool operator==(std::nullptr_t) const { return value_ == nullptr; }
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator!=(const WeakRefCountedPtr<Y>& other) const {
return value_ != other.value_;
}
- template <typename Y>
+ template <typename Y,
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
bool operator!=(const Y* other) const {
return value_ != other;
}
diff --git a/src/core/lib/gprpp/ref_counted_string.h b/src/core/lib/gprpp/ref_counted_string.h
index 8bcdb87eea..dbe32b113d 100644
--- a/src/core/lib/gprpp/ref_counted_string.h
+++ b/src/core/lib/gprpp/ref_counted_string.h
@@ -21,6 +21,8 @@
#include <stddef.h>
+#include <string>
+
#include "absl/strings/string_view.h"
#include "src/core/lib/gprpp/ref_counted.h"
@@ -102,6 +104,19 @@ inline bool operator==(const RefCountedStringValue& lhs,
return lhs.as_string_view() == rhs.as_string_view();
}
+inline bool operator!=(const RefCountedStringValue& lhs,
+ absl::string_view rhs) {
+ return lhs.as_string_view() != rhs;
+}
+inline bool operator!=(absl::string_view lhs,
+ const RefCountedStringValue& rhs) {
+ return lhs != rhs.as_string_view();
+}
+inline bool operator!=(const RefCountedStringValue& lhs,
+ const RefCountedStringValue& rhs) {
+ return lhs.as_string_view() != rhs.as_string_view();
+}
+
inline bool operator<(const RefCountedStringValue& lhs, absl::string_view rhs) {
return lhs.as_string_view() < rhs;
}
diff --git a/src/core/lib/gprpp/status_helper.cc b/src/core/lib/gprpp/status_helper.cc
index bb6c84e81b..85302a985b 100644
--- a/src/core/lib/gprpp/status_helper.cc
+++ b/src/core/lib/gprpp/status_helper.cc
@@ -22,7 +22,6 @@
#include <string.h>
-#include <algorithm>
#include <utility>
#include "absl/strings/cord.h"
@@ -35,8 +34,7 @@
#include "google/protobuf/any.upb.h"
#include "google/rpc/status.upb.h"
#include "upb/base/string_view.h"
-#include "upb/mem/arena.h"
-#include "upb/upb.hpp"
+#include "upb/mem/arena.hpp"
#include <grpc/support/log.h>
diff --git a/src/core/lib/gprpp/strerror.cc b/src/core/lib/gprpp/strerror.cc
index d2d3e9f926..021e61ba48 100644
--- a/src/core/lib/gprpp/strerror.cc
+++ b/src/core/lib/gprpp/strerror.cc
@@ -18,8 +18,6 @@
#include <string.h>
-#include <initializer_list>
-
#include "absl/strings/str_format.h"
namespace grpc_core {
diff --git a/src/core/lib/gprpp/time.cc b/src/core/lib/gprpp/time.cc
index 40ba366c57..ba04e3347f 100644
--- a/src/core/lib/gprpp/time.cc
+++ b/src/core/lib/gprpp/time.cc
@@ -18,7 +18,6 @@
#include <atomic>
#include <chrono>
-#include <initializer_list>
#include <limits>
#include <string>
#include <utility>
diff --git a/src/core/lib/gprpp/uuid_v4.cc b/src/core/lib/gprpp/uuid_v4.cc
index ee98556f94..5c3f3cd8e3 100644
--- a/src/core/lib/gprpp/uuid_v4.cc
+++ b/src/core/lib/gprpp/uuid_v4.cc
@@ -20,8 +20,6 @@
#include "src/core/lib/gprpp/uuid_v4.h"
-#include <initializer_list>
-
#include "absl/strings/str_format.h"
namespace grpc_core {
diff --git a/src/core/lib/gprpp/validation_errors.cc b/src/core/lib/gprpp/validation_errors.cc
index d6fecce934..fd6402e0f3 100644
--- a/src/core/lib/gprpp/validation_errors.cc
+++ b/src/core/lib/gprpp/validation_errors.cc
@@ -16,7 +16,6 @@
#include "src/core/lib/gprpp/validation_errors.h"
-#include <algorithm>
#include <utility>
#include "absl/status/status.h"
diff --git a/src/core/lib/gprpp/windows/directory_reader.cc b/src/core/lib/gprpp/windows/directory_reader.cc
new file mode 100644
index 0000000000..3d45ee6532
--- /dev/null
+++ b/src/core/lib/gprpp/windows/directory_reader.cc
@@ -0,0 +1,81 @@
+//
+//
+// Copyright 2023 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//
+
+#include <grpc/support/port_platform.h>
+
+#if defined(GPR_WINDOWS)
+
+#include <sys/stat.h>
+#include <windows.h>
+
+#include <string>
+#include <vector>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+
+#include <grpc/support/log.h>
+
+#include "src/core/lib/gprpp/directory_reader.h"
+namespace grpc_core {
+
+namespace {
+const char kSkipEntriesSelf[] = ".";
+const char kSkipEntriesParent[] = "..";
+} // namespace
+
+class DirectoryReaderImpl : public DirectoryReader {
+ public:
+ explicit DirectoryReaderImpl(absl::string_view directory_path)
+ : directory_path_(directory_path) {}
+ absl::string_view Name() const override { return directory_path_; }
+ absl::Status ForEach(absl::FunctionRef<void(absl::string_view)>) override;
+
+ private:
+ const std::string directory_path_;
+};
+
+std::unique_ptr<DirectoryReader> MakeDirectoryReader(
+ absl::string_view filename) {
+ return std::make_unique<DirectoryReaderImpl>(filename);
+}
+
+// Reference for reading directory in Windows:
+// https://stackoverflow.com/questions/612097/how-can-i-get-the-list-of-files-in-a-directory-using-c-or-c
+// https://learn.microsoft.com/en-us/windows/win32/fileio/listing-the-files-in-a-directory
+absl::Status DirectoryReaderImpl::ForEach(
+ absl::FunctionRef<void(absl::string_view)> callback) {
+ std::string search_path = absl::StrCat(directory_path_, "/*");
+ WIN32_FIND_DATAA find_data;
+ HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &find_data);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ return absl::InternalError("Could not read crl directory.");
+ }
+ do {
+ if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ callback(find_data.cFileName);
+ }
+ } while (::FindNextFileA(hFind, &find_data));
+ ::FindClose(hFind);
+ return absl::OkStatus();
+}
+
+} // namespace grpc_core
+
+#endif // GPR_WINDOWS
diff --git a/src/core/lib/gprpp/work_serializer.cc b/src/core/lib/gprpp/work_serializer.cc
index 530238d549..1959deed98 100644
--- a/src/core/lib/gprpp/work_serializer.cc
+++ b/src/core/lib/gprpp/work_serializer.cc
@@ -262,6 +262,9 @@ void WorkSerializer::LegacyWorkSerializer::DrainQueueOwned() {
}
// There is at least one callback on the queue. Pop the callback from the
// queue and execute it.
+ if (IsWorkSerializerClearsTimeCacheEnabled() && ExecCtx::Get() != nullptr) {
+ ExecCtx::Get()->InvalidateNow();
+ }
CallbackWrapper* cb_wrapper = nullptr;
bool empty_unused;
while ((cb_wrapper = reinterpret_cast<CallbackWrapper*>(
diff --git a/src/core/lib/gprpp/xxhash_inline.h b/src/core/lib/gprpp/xxhash_inline.h
new file mode 100644
index 0000000000..6b12c71121
--- /dev/null
+++ b/src/core/lib/gprpp/xxhash_inline.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2023 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef GRPC_SRC_CORE_LIB_GPRPP_XXHASH_INLINE_H
+#define GRPC_SRC_CORE_LIB_GPRPP_XXHASH_INLINE_H
+
+#include <grpc/support/port_platform.h>
+
+// This header is a simple wrapper around the third-party xxhash
+// library, so that we don't need to define XXH_INLINE_ALL in every file
+// that includes xxhash.h. That definition confuses clang-format's
+// ordering of includes.
+#define XXH_INLINE_ALL
+#include "xxhash.h"
+
+#endif // GRPC_SRC_CORE_LIB_GPRPP_XXHASH_INLINE_H