diff options
Diffstat (limited to 'absl/base/call_once.h')
-rw-r--r-- | absl/base/call_once.h | 24 |
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)) { |