aboutsummaryrefslogtreecommitdiff
path: root/absl/base/call_once.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/base/call_once.h')
-rw-r--r--absl/base/call_once.h24
1 files changed, 15 insertions, 9 deletions
diff --git a/absl/base/call_once.h b/absl/base/call_once.h
index 08436bac..7b0e69cc 100644
--- a/absl/base/call_once.h
+++ b/absl/base/call_once.h
@@ -37,6 +37,7 @@
#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/spinlock_wait.h"
#include "absl/base/macros.h"
+#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
@@ -46,7 +47,8 @@ ABSL_NAMESPACE_BEGIN
class once_flag;
namespace base_internal {
-std::atomic<uint32_t>* ControlWord(absl::once_flag* flag);
+absl::Nonnull<std::atomic<uint32_t>*> ControlWord(
+ absl::Nonnull<absl::once_flag*> flag);
} // namespace base_internal
// call_once()
@@ -89,7 +91,8 @@ class once_flag {
once_flag& operator=(const once_flag&) = delete;
private:
- friend std::atomic<uint32_t>* base_internal::ControlWord(once_flag* flag);
+ friend absl::Nonnull<std::atomic<uint32_t>*> base_internal::ControlWord(
+ absl::Nonnull<once_flag*> flag);
std::atomic<uint32_t> control_;
};
@@ -103,7 +106,8 @@ namespace base_internal {
// Like call_once, but uses KERNEL_ONLY scheduling. Intended to be used to
// initialize entities used by the scheduler implementation.
template <typename Callable, typename... Args>
-void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args);
+void LowLevelCallOnce(absl::Nonnull<absl::once_flag*> flag, Callable&& fn,
+ Args&&... args);
// Disables scheduling while on stack when scheduling mode is non-cooperative.
// No effect for cooperative scheduling modes.
@@ -143,10 +147,10 @@ enum {
};
template <typename Callable, typename... Args>
-ABSL_ATTRIBUTE_NOINLINE
-void CallOnceImpl(std::atomic<uint32_t>* control,
- base_internal::SchedulingMode scheduling_mode, Callable&& fn,
- Args&&... args) {
+ABSL_ATTRIBUTE_NOINLINE void CallOnceImpl(
+ absl::Nonnull<std::atomic<uint32_t>*> control,
+ base_internal::SchedulingMode scheduling_mode, Callable&& fn,
+ Args&&... args) {
#ifndef NDEBUG
{
uint32_t old_control = control->load(std::memory_order_relaxed);
@@ -185,12 +189,14 @@ void CallOnceImpl(std::atomic<uint32_t>* control,
} // else *control is already kOnceDone
}
-inline std::atomic<uint32_t>* ControlWord(once_flag* flag) {
+inline absl::Nonnull<std::atomic<uint32_t>*> ControlWord(
+ absl::Nonnull<once_flag*> flag) {
return &flag->control_;
}
template <typename Callable, typename... Args>
-void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args) {
+void LowLevelCallOnce(absl::Nonnull<absl::once_flag*> flag, Callable&& fn,
+ Args&&... args) {
std::atomic<uint32_t>* once = base_internal::ControlWord(flag);
uint32_t s = once->load(std::memory_order_acquire);
if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) {