diff options
Diffstat (limited to 'absl/flags/internal/flag.h')
-rw-r--r-- | absl/flags/internal/flag.h | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index a84f7fa8d304..16330380f548 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -16,12 +16,16 @@ #ifndef ABSL_FLAGS_INTERNAL_FLAG_H_ #define ABSL_FLAGS_INTERNAL_FLAG_H_ +#include <cstring> + #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/registry.h" namespace absl { namespace flags_internal { +constexpr int64_t AtomicInit() { return 0xababababababababll; } + // Signature for the mutation callback used by watched Flags // The callback is noexcept. // TODO(rogeeff): add noexcept after C++17 support is added. @@ -44,6 +48,7 @@ class Flag final : public flags_internal::CommandLineFlag { initial_value_gen, /*def=*/nullptr, /*cur=*/nullptr), + atomic_(flags_internal::AtomicInit()), callback_(nullptr) {} T Get() const { @@ -76,8 +81,8 @@ class Flag final : public flags_internal::CommandLineFlag { bool AtomicGet(T* v) const { const int64_t r = atomic_.load(std::memory_order_acquire); - if (r != flags_internal::CommandLineFlag::kAtomicInit) { - memcpy(v, &r, sizeof(T)); + if (r != flags_internal::AtomicInit()) { + std::memcpy(v, &r, sizeof(T)); return true; } @@ -108,7 +113,18 @@ class Flag final : public flags_internal::CommandLineFlag { delete locks_; } + void StoreAtomic() override { + if (sizeof(T) <= sizeof(int64_t)) { + int64_t t = 0; + std::memcpy(&t, cur_, (std::min)(sizeof(T), sizeof(int64_t))); + atomic_.store(t, std::memory_order_release); + } + } + // Flag's data + // For some types, a copy of the current value is kept in an atomically + // accessible field. + std::atomic<int64_t> atomic_; FlagCallback callback_; // Mutation callback }; |