aboutsummaryrefslogtreecommitdiffhomepage
path: root/absl/flags/internal/flag.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2019-08-23 11:38:04 -0700
committerGravatar Xiaoyi Zhang <zhangxy@google.com>2019-08-23 14:48:13 -0400
commit2d2d7fbc283315b676159716376e739d3d23ed94 (patch)
tree6530edfdc7591c4f89d0aa48442cc6d452c47735 /absl/flags/internal/flag.h
parent0302d1e5fa4fcdd1763b7d1bb3212943b1ae911d (diff)
Export of internal Abseil changes
-- d6748c733a70cd74ad9b76a0c9cd6b3fe2cecacf by Xiaoyi Zhang <zhangxy@google.com>: Remove empty block, to address alerts reported in https://github.com/abseil/abseil-cpp/issues/368. PiperOrigin-RevId: 265099887 -- 232e2036b5668d6d1296b881f9347756d84541ee by Derek Mauro <dmauro@google.com>: Make the Linux Bazel CI scripts test with the exception mode explicitly set. PiperOrigin-RevId: 265092105 -- 942a40696c2c9b833be03e92d22a6ede7bccb6d4 by Xiaoyi Zhang <zhangxy@google.com>: Import https://github.com/abseil/abseil-cpp/pull/372. Suppress the unused variable warning on GCC, i.e. "-Wunused-variable". PiperOrigin-RevId: 265063925 -- 7ef90796b52cbdc260afc77cf47206f9356471d0 by Xiaoyi Zhang <zhangxy@google.com>: Add quotes to `ABSL_COMMON_INCLUDE_DIRS` since it's a list and may contain a `;`. This addresses https://github.com/abseil/abseil-cpp/issues/373. PiperOrigin-RevId: 265059077 -- 43f3ae742e00b83672ad6c5bc5b17fdb8f9fe6fe by Gennadiy Rozental <rogeeff@google.com>: Internal re-organization PiperOrigin-RevId: 264913945 -- 6a2adf9c08ee1d98cc6b2855a676345c6495294a by Andy Soffer <asoffer@google.com>: Publicly expose type names for uniform interval tags as in, for example, absl::IntervalClosedClosedTag, and add equality comparison operators. PiperOrigin-RevId: 264861162 -- 3c90c6e05fd61d56b419cd2d39dab8f17b8711b8 by Abseil Team <absl-team@google.com>: Add validity check on returned frame pointer. PiperOrigin-RevId: 264858823 -- 2db87e0cfa0c6bea7ba81684b834cb8a73b7d748 by Gennadiy Rozental <rogeeff@google.com>: Add MUST_USE_RESULT attribute to absl::GetFlag to prevent accidental misuse. PiperOrigin-RevId: 264782762 GitOrigin-RevId: d6748c733a70cd74ad9b76a0c9cd6b3fe2cecacf Change-Id: I169e9c5358e4f63000c1255e806d26b8afecf5ff
Diffstat (limited to 'absl/flags/internal/flag.h')
-rw-r--r--absl/flags/internal/flag.h49
1 files changed, 42 insertions, 7 deletions
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index bc50de5..fad3687 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -22,20 +22,30 @@
namespace absl {
namespace flags_internal {
+// Signature for the mutation callback used by watched Flags
+// The callback is noexcept.
+// TODO(rogeeff): add noexcept after C++17 support is added.
+using FlagCallback = void (*)();
+
+void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu,
+ FlagCallback cb) EXCLUSIVE_LOCKS_REQUIRED(primary_mu);
+
// This is "unspecified" implementation of absl::Flag<T> type.
template <typename T>
-class Flag : public flags_internal::CommandLineFlag {
+class Flag final : public flags_internal::CommandLineFlag {
public:
- constexpr Flag(const char* name, const flags_internal::HelpGenFunc help_gen,
- const char* filename,
+ constexpr Flag(const char* name_arg,
+ const flags_internal::HelpGenFunc help_gen,
+ const char* filename_arg,
const flags_internal::FlagMarshallingOpFn marshalling_op_arg,
const flags_internal::InitialValGenFunc initial_value_gen)
: flags_internal::CommandLineFlag(
- name, flags_internal::HelpText::FromFunctionPointer(help_gen),
- filename, &flags_internal::FlagOps<T>, marshalling_op_arg,
+ name_arg, flags_internal::HelpText::FromFunctionPointer(help_gen),
+ filename_arg, &flags_internal::FlagOps<T>, marshalling_op_arg,
initial_value_gen,
- /*retired_arg=*/false, /*def_arg=*/nullptr,
- /*cur_arg=*/nullptr) {}
+ /*def_arg=*/nullptr,
+ /*cur_arg=*/nullptr),
+ callback_(nullptr) {}
T Get() const {
// Implementation notes:
@@ -76,6 +86,31 @@ class Flag : public flags_internal::CommandLineFlag {
}
void Set(const T& v) { this->Write(&v, &flags_internal::FlagOps<T>); }
+
+ void SetCallback(const flags_internal::FlagCallback mutation_callback) {
+ absl::MutexLock l(InitFlagIfNecessary());
+
+ callback_ = mutation_callback;
+
+ InvokeCallback();
+ }
+ void InvokeCallback() override
+ EXCLUSIVE_LOCKS_REQUIRED(this->locks->primary_mu) {
+ flags_internal::InvokeCallback(&this->locks->primary_mu,
+ &this->locks->callback_mu, callback_);
+ }
+
+ private:
+ void Destroy() const override {
+ // Values are heap allocated Abseil Flags.
+ if (this->cur) Delete(this->op, this->cur);
+ if (this->def) Delete(this->op, this->def);
+
+ delete this->locks;
+ }
+
+ // Flag's data
+ FlagCallback callback_; // Mutation callback
};
// This class facilitates Flag object registration and tail expression-based