Export of internal Abseil changes

--
972333fe1e43427849b8a634aa35061e81be3642 by Abseil Team <absl-team@google.com>:

Replace deprecated thread annotations macros.

PiperOrigin-RevId: 267332619

--
7039c6dc499a31c372b4872eda0772455931c360 by Gennadiy Rozental <rogeeff@google.com>:

Internal change

PiperOrigin-RevId: 267220271

--
a3f524d2afc2535686f206a7ce06961016349d7a by Abseil Team <absl-team@google.com>:

Factor kernel_timeout out of synchronization.

PiperOrigin-RevId: 267217304

--
90287de4114ef9a06cafe50256a2d03349772c21 by Abseil Team <absl-team@google.com>:

Fixed comment typo.

PiperOrigin-RevId: 267198532

--
d312c1a1e52aeca1871ff0deead416d09a7f237e by Gennadiy Rozental <rogeeff@google.com>:

Internal change

PiperOrigin-RevId: 267185804
GitOrigin-RevId: 972333fe1e43427849b8a634aa35061e81be3642
Change-Id: Ia8a2f877c57cef9854aad48f1753af872fc04dc8
This commit is contained in:
Abseil Team 2019-09-05 02:54:58 -07:00 committed by Gennadiy Rozental
parent eb6b7bd23b
commit 83c1d65c90
27 changed files with 282 additions and 377 deletions

View file

@ -58,55 +58,55 @@ absl::Mutex* InitFlag(CommandLineFlag* flag) {
{
absl::MutexLock lock(&init_lock);
if (flag->locks == nullptr) { // Must initialize Mutexes for this flag.
flag->locks = new flags_internal::CommandLineFlagLocks;
if (flag->locks_ == nullptr) { // Must initialize Mutexes for this flag.
flag->locks_ = new flags_internal::CommandLineFlagLocks;
}
mu = &flag->locks->primary_mu;
mu = &flag->locks_->primary_mu;
}
{
absl::MutexLock lock(mu);
if (!flag->IsRetired() && flag->def == nullptr) {
if (!flag->IsRetired() && flag->def_ == nullptr) {
// Need to initialize def and cur fields.
flag->def = (*flag->make_init_value)();
flag->cur = Clone(flag->op, flag->def);
flag->def_ = (*flag->make_init_value_)();
flag->cur_ = Clone(flag->op_, flag->def_);
UpdateCopy(flag);
flag->inited.store(true, std::memory_order_release);
flag->inited_.store(true, std::memory_order_release);
flag->InvokeCallback();
}
}
flag->inited.store(true, std::memory_order_release);
flag->inited_.store(true, std::memory_order_release);
return mu;
}
// Ensure that the lazily initialized fields of *flag have been initialized,
// and return &flag->locks->primary_mu.
// and return &flag->locks_->primary_mu.
absl::Mutex* CommandLineFlag::InitFlagIfNecessary() const
LOCK_RETURNED(locks->primary_mu) {
if (!this->inited.load(std::memory_order_acquire)) {
ABSL_LOCK_RETURNED(locks_->primary_mu) {
if (!inited_.load(std::memory_order_acquire)) {
return InitFlag(const_cast<CommandLineFlag*>(this));
}
// All fields initialized; this->locks is therefore safe to read.
return &this->locks->primary_mu;
// All fields initialized; locks_ is therefore safe to read.
return &locks_->primary_mu;
}
bool CommandLineFlag::IsModified() const {
absl::MutexLock l(InitFlagIfNecessary());
return modified;
return modified_;
}
void CommandLineFlag::SetModified(bool is_modified) {
absl::MutexLock l(InitFlagIfNecessary());
modified = is_modified;
modified_ = is_modified;
}
bool CommandLineFlag::IsSpecifiedOnCommandLine() const {
absl::MutexLock l(InitFlagIfNecessary());
return on_command_line;
return on_command_line_;
}
absl::string_view CommandLineFlag::Typename() const {
@ -134,19 +134,19 @@ absl::string_view CommandLineFlag::Typename() const {
}
std::string CommandLineFlag::Filename() const {
return flags_internal::GetUsageConfig().normalize_filename(this->filename);
return flags_internal::GetUsageConfig().normalize_filename(filename_);
}
std::string CommandLineFlag::DefaultValue() const {
absl::MutexLock l(InitFlagIfNecessary());
return Unparse(this->marshalling_op, this->def);
return Unparse(marshalling_op_, def_);
}
std::string CommandLineFlag::CurrentValue() const {
absl::MutexLock l(InitFlagIfNecessary());
return Unparse(this->marshalling_op, this->cur);
return Unparse(marshalling_op_, cur_);
}
// Attempts to parse supplied `value` string using parsing routine in the `flag`
@ -157,31 +157,31 @@ std::string CommandLineFlag::CurrentValue() const {
// in 'err'
bool TryParseLocked(CommandLineFlag* flag, void* dst, absl::string_view value,
std::string* err)
EXCLUSIVE_LOCKS_REQUIRED(flag->locks->primary_mu) {
void* tentative_value = Clone(flag->op, flag->def);
ABSL_EXCLUSIVE_LOCKS_REQUIRED(flag->locks_->primary_mu) {
void* tentative_value = Clone(flag->op_, flag->def_);
std::string parse_err;
if (!Parse(flag->marshalling_op, value, tentative_value, &parse_err)) {
if (!Parse(flag->marshalling_op_, value, tentative_value, &parse_err)) {
auto type_name = flag->Typename();
absl::string_view err_sep = parse_err.empty() ? "" : "; ";
absl::string_view typename_sep = type_name.empty() ? "" : " ";
*err = absl::StrCat("Illegal value '", value, "' specified for",
typename_sep, type_name, " flag '", flag->Name(), "'",
err_sep, parse_err);
Delete(flag->op, tentative_value);
Delete(flag->op_, tentative_value);
return false;
}
if (!flag->InvokeValidator(tentative_value)) {
*err = absl::StrCat("Failed validation of new value '",
Unparse(flag->marshalling_op, tentative_value),
Unparse(flag->marshalling_op_, tentative_value),
"' for flag '", flag->Name(), "'");
Delete(flag->op, tentative_value);
Delete(flag->op_, tentative_value);
return false;
}
flag->counter++;
Copy(flag->op, tentative_value, dst);
Delete(flag->op, tentative_value);
flag->counter_++;
Copy(flag->op_, tentative_value, dst);
Delete(flag->op_, tentative_value);
return true;
}
@ -201,38 +201,38 @@ bool CommandLineFlag::SetFromString(absl::string_view value,
absl::MutexLock l(InitFlagIfNecessary());
// Direct-access flags can be modified without going through the
// flag API. Detect such changes and update the flag->modified bit.
// flag API. Detect such changes and update the flag->modified_ bit.
if (!IsAbseilFlag()) {
if (!this->modified && ChangedDirectly(this, this->cur, this->def)) {
this->modified = true;
if (!modified_ && ChangedDirectly(this, cur_, def_)) {
modified_ = true;
}
}
switch (set_mode) {
case SET_FLAGS_VALUE: {
// set or modify the flag's value
if (!TryParseLocked(this, this->cur, value, err)) return false;
this->modified = true;
if (!TryParseLocked(this, cur_, value, err)) return false;
modified_ = true;
UpdateCopy(this);
InvokeCallback();
if (source == kCommandLine) {
this->on_command_line = true;
on_command_line_ = true;
}
break;
}
case SET_FLAG_IF_DEFAULT: {
// set the flag's value, but only if it hasn't been set by someone else
if (!this->modified) {
if (!TryParseLocked(this, this->cur, value, err)) return false;
this->modified = true;
if (!modified_) {
if (!TryParseLocked(this, cur_, value, err)) return false;
modified_ = true;
UpdateCopy(this);
InvokeCallback();
} else {
// TODO(rogeeff): review and fix this semantic. Currently we do not fail
// in this case if flag is modified. This is misleading since the flag's
// value is not updated even though we return true.
// *err = absl::StrCat(this->Name(), " is already set to ",
// *err = absl::StrCat(Name(), " is already set to ",
// CurrentValue(), "\n");
// return false;
return true;
@ -241,11 +241,11 @@ bool CommandLineFlag::SetFromString(absl::string_view value,
}
case SET_FLAGS_DEFAULT: {
// modify the flag's default-value
if (!TryParseLocked(this, this->def, value, err)) return false;
if (!TryParseLocked(this, def_, value, err)) return false;
if (!this->modified) {
if (!modified_) {
// Need to set both defvalue *and* current, in this case
Copy(this->op, this->def, this->cur);
Copy(op_, def_, cur_);
UpdateCopy(this);
InvokeCallback();
}
@ -264,8 +264,8 @@ bool CommandLineFlag::SetFromString(absl::string_view value,
void CommandLineFlag::StoreAtomic(size_t size) {
int64_t t = 0;
assert(size <= sizeof(int64_t));
memcpy(&t, this->cur, size);
this->atomic.store(t, std::memory_order_release);
memcpy(&t, cur_, size);
atomic_.store(t, std::memory_order_release);
}
void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const {
@ -273,9 +273,9 @@ void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const {
absl::MutexLock lock(InitFlagIfNecessary());
void* dst = Clone(this->op, this->def);
void* dst = Clone(op_, def_);
std::string error;
if (!flags_internal::Parse(this->marshalling_op, v, dst, &error)) {
if (!flags_internal::Parse(marshalling_op_, v, dst, &error)) {
ABSL_INTERNAL_LOG(
FATAL,
absl::StrCat("Flag ", Name(), " (from ", Filename(),
@ -285,23 +285,23 @@ void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const {
// We do not compare dst to def since parsing/unparsing may make
// small changes, e.g., precision loss for floating point types.
Delete(this->op, dst);
Delete(op_, dst);
}
bool CommandLineFlag::ValidateDefaultValue() const {
absl::MutexLock lock(InitFlagIfNecessary());
return InvokeValidator(this->def);
return InvokeValidator(def_);
}
bool CommandLineFlag::ValidateInputValue(absl::string_view value) const {
absl::MutexLock l(InitFlagIfNecessary()); // protect default value access
void* obj = Clone(this->op, this->def);
void* obj = Clone(op_, def_);
std::string ignored_error;
const bool result =
flags_internal::Parse(this->marshalling_op, value, obj, &ignored_error) &&
flags_internal::Parse(marshalling_op_, value, obj, &ignored_error) &&
InvokeValidator(obj);
Delete(this->op, obj);
Delete(op_, obj);
return result;
}
@ -314,13 +314,13 @@ void CommandLineFlag::Read(void* dst,
// `dst_op` is the unmarshaling operation corresponding to the declaration
// visibile at the call site. `op` is the Flag's defined unmarshalling
// operation. They must match for this operation to be well-defined.
if (ABSL_PREDICT_FALSE(dst_op != op)) {
if (ABSL_PREDICT_FALSE(dst_op != op_)) {
ABSL_INTERNAL_LOG(
ERROR,
absl::StrCat("Flag '", name,
absl::StrCat("Flag '", Name(),
"' is defined as one type and declared as another"));
}
CopyConstruct(op, cur, dst);
CopyConstruct(op_, cur_, dst);
}
void CommandLineFlag::Write(const void* src,
@ -330,28 +330,28 @@ void CommandLineFlag::Write(const void* src,
// `src_op` is the marshalling operation corresponding to the declaration
// visible at the call site. `op` is the Flag's defined marshalling operation.
// They must match for this operation to be well-defined.
if (ABSL_PREDICT_FALSE(src_op != op)) {
if (ABSL_PREDICT_FALSE(src_op != op_)) {
ABSL_INTERNAL_LOG(
ERROR,
absl::StrCat("Flag '", name,
absl::StrCat("Flag '", Name(),
"' is defined as one type and declared as another"));
}
if (ShouldValidateFlagValue(*this)) {
void* obj = Clone(op, src);
void* obj = Clone(op_, src);
std::string ignored_error;
std::string src_as_str = Unparse(marshalling_op, src);
if (!Parse(marshalling_op, src_as_str, obj, &ignored_error) ||
std::string src_as_str = Unparse(marshalling_op_, src);
if (!Parse(marshalling_op_, src_as_str, obj, &ignored_error) ||
!InvokeValidator(obj)) {
ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", name,
ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(),
"' to invalid value ", src_as_str));
}
Delete(op, obj);
Delete(op_, obj);
}
modified = true;
counter++;
Copy(op, src, cur);
modified_ = true;
counter_++;
Copy(op_, src, cur_);
UpdateCopy(this);
InvokeCallback();

View file

@ -69,8 +69,6 @@ using HelpGenFunc = std::string (*)();
// based on default value supplied in flag's definition)
using InitialValGenFunc = void* (*)();
struct CommandLineFlagInfo;
extern const char kStrippedFlagHelp[];
// The per-type function
@ -189,27 +187,28 @@ class HelpText {
};
// Holds all information for a flag.
struct CommandLineFlag {
class CommandLineFlag {
public:
constexpr CommandLineFlag(
const char* name_arg, HelpText help_text, const char* filename_arg,
const flags_internal::FlagOpFn op_arg,
const flags_internal::FlagMarshallingOpFn marshalling_op_arg,
const flags_internal::InitialValGenFunc initial_value_gen, void* def_arg,
void* cur_arg)
: name(name_arg),
help(help_text),
filename(filename_arg),
op(op_arg),
marshalling_op(marshalling_op_arg),
make_init_value(initial_value_gen),
inited(false),
modified(false),
on_command_line(false),
def(def_arg),
cur(cur_arg),
counter(0),
atomic(kAtomicInit),
locks(nullptr) {}
const char* name, HelpText help_text, const char* filename,
const flags_internal::FlagOpFn op,
const flags_internal::FlagMarshallingOpFn marshalling_op,
const flags_internal::InitialValGenFunc initial_value_gen, void* def,
void* cur)
: name_(name),
help_(help_text),
filename_(filename),
op_(op),
marshalling_op_(marshalling_op),
make_init_value_(initial_value_gen),
inited_(false),
modified_(false),
on_command_line_(false),
def_(def),
cur_(cur),
counter_(0),
atomic_(kAtomicInit),
locks_(nullptr) {}
// Virtual destructor
virtual void Destroy() const = 0;
@ -225,8 +224,8 @@ struct CommandLineFlag {
// Returns true iff this is a handle to an Abseil Flag.
virtual bool IsAbseilFlag() const { return true; }
absl::string_view Name() const { return name; }
std::string Help() const { return help.GetHelpText(); }
absl::string_view Name() const { return name_; }
std::string Help() const { return help_.GetHelpText(); }
bool IsModified() const;
void SetModified(bool is_modified);
bool IsSpecifiedOnCommandLine() const;
@ -247,15 +246,14 @@ struct CommandLineFlag {
// Return true iff flag has type T.
template <typename T>
inline bool IsOfType() const {
return this->op == &flags_internal::FlagOps<T>;
return op_ == &flags_internal::FlagOps<T>;
}
// Attempts to retrieve the flag value. Returns value on success,
// absl::nullopt otherwise.
template <typename T>
absl::optional<T> Get() const {
if (IsRetired() || flags_internal::FlagOps<T> != this->op)
return absl::nullopt;
if (IsRetired() || flags_internal::FlagOps<T> != op_) return absl::nullopt;
T res;
Read(&res, flags_internal::FlagOps<T>);
@ -286,36 +284,36 @@ struct CommandLineFlag {
protected:
~CommandLineFlag() = default;
const char* const name;
const HelpText help;
const char* const filename;
const char* const name_;
const HelpText help_;
const char* const filename_;
const FlagOpFn op; // Type-specific handler
const FlagMarshallingOpFn marshalling_op; // Marshalling ops handler
const InitialValGenFunc make_init_value; // Makes initial value for the flag
std::atomic<bool> inited; // fields have been lazily initialized
const FlagOpFn op_; // Type-specific handler
const FlagMarshallingOpFn marshalling_op_; // Marshalling ops handler
const InitialValGenFunc make_init_value_; // Makes initial value for the flag
std::atomic<bool> inited_; // fields have been lazily initialized
// Mutable state (guarded by locks->primary_mu).
bool modified; // Has flag value been modified?
bool on_command_line; // Specified on command line.
void* def; // Lazily initialized pointer to default value
void* cur; // Lazily initialized pointer to current value
int64_t counter; // Mutation counter
// Mutable state (guarded by locks_->primary_mu).
bool modified_; // Has flag value been modified?
bool on_command_line_; // Specified on command line.
void* def_; // Lazily initialized pointer to default value
void* cur_; // Lazily initialized pointer to current value
int64_t counter_; // Mutation counter
// For some types, a copy of the current value is kept in an atomically
// accessible field.
static const int64_t kAtomicInit = 0xababababababababll;
std::atomic<int64_t> atomic;
std::atomic<int64_t> atomic_;
// Lazily initialized mutexes for this flag value. We cannot inline a
// SpinLock or Mutex here because those have non-constexpr constructors and
// so would prevent constant initialization of this type.
// TODO(rogeeff): fix it once Mutex has constexpr constructor
struct CommandLineFlagLocks* locks; // locks, laziliy allocated.
struct CommandLineFlagLocks* locks_; // locks, laziliy allocated.
// Ensure that the lazily initialized fields of *flag have been initialized,
// and return the lock which should be locked when flag's state is mutated.
absl::Mutex* InitFlagIfNecessary() const LOCK_RETURNED(locks->primary_mu);
absl::Mutex* InitFlagIfNecessary() const ABSL_LOCK_RETURNED(locks_->primary_mu);
// copy construct new value of flag's type in a memory referenced by dst
// based on current flag's value
@ -326,8 +324,6 @@ struct CommandLineFlag {
friend class FlagRegistry;
friend class FlagPtrMap;
friend class FlagSaverImpl;
friend void FillCommandLineFlagInfo(CommandLineFlag* flag,
CommandLineFlagInfo* result);
friend bool TryParseLocked(CommandLineFlag* flag, void* dst,
absl::string_view value, std::string* err);
friend absl::Mutex* InitFlag(CommandLineFlag* flag);
@ -335,7 +331,7 @@ struct CommandLineFlag {
// This is a short term, until we completely rework persistent state
// storage API.
virtual void* GetValidator() const { return nullptr; }
virtual void SetValidator(void*) {}
virtual bool SetValidator(void*) { return false; }
};
// Update any copy of the flag value that is stored in an atomic word.

View file

@ -32,7 +32,7 @@ namespace flags_internal {
// completed. Requires that *primary_lock be held in exclusive mode; it may be
// released and reacquired by the implementation.
void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu,
FlagCallback cb) EXCLUSIVE_LOCKS_REQUIRED(primary_mu) {
FlagCallback cb) ABSL_EXCLUSIVE_LOCKS_REQUIRED(primary_mu) {
if (!cb) return;
// When executing the callback we need the primary flag's mutex to be

View file

@ -28,23 +28,22 @@ namespace flags_internal {
using FlagCallback = void (*)();
void InvokeCallback(absl::Mutex* primary_mu, absl::Mutex* callback_mu,
FlagCallback cb) EXCLUSIVE_LOCKS_REQUIRED(primary_mu);
FlagCallback cb) ABSL_EXCLUSIVE_LOCKS_REQUIRED(primary_mu);
// This is "unspecified" implementation of absl::Flag<T> type.
template <typename T>
class Flag final : public flags_internal::CommandLineFlag {
public:
constexpr Flag(const char* name_arg,
const flags_internal::HelpGenFunc help_gen,
const char* filename_arg,
const flags_internal::FlagMarshallingOpFn marshalling_op_arg,
constexpr Flag(const char* name, const flags_internal::HelpGenFunc help_gen,
const char* filename,
const flags_internal::FlagMarshallingOpFn marshalling_op,
const flags_internal::InitialValGenFunc initial_value_gen)
: flags_internal::CommandLineFlag(
name_arg, flags_internal::HelpText::FromFunctionPointer(help_gen),
filename_arg, &flags_internal::FlagOps<T>, marshalling_op_arg,
name, flags_internal::HelpText::FromFunctionPointer(help_gen),
filename, &flags_internal::FlagOps<T>, marshalling_op,
initial_value_gen,
/*def_arg=*/nullptr,
/*cur_arg=*/nullptr),
/*def=*/nullptr,
/*cur=*/nullptr),
callback_(nullptr) {}
T Get() const {
@ -71,12 +70,12 @@ class Flag final : public flags_internal::CommandLineFlag {
};
U u;
this->Read(&u.value, &flags_internal::FlagOps<T>);
Read(&u.value, &flags_internal::FlagOps<T>);
return std::move(u.value);
}
bool AtomicGet(T* v) const {
const int64_t r = this->atomic.load(std::memory_order_acquire);
const int64_t r = atomic_.load(std::memory_order_acquire);
if (r != flags_internal::CommandLineFlag::kAtomicInit) {
memcpy(v, &r, sizeof(T));
return true;
@ -85,7 +84,7 @@ class Flag final : public flags_internal::CommandLineFlag {
return false;
}
void Set(const T& v) { this->Write(&v, &flags_internal::FlagOps<T>); }
void Set(const T& v) { Write(&v, &flags_internal::FlagOps<T>); }
void SetCallback(const flags_internal::FlagCallback mutation_callback) {
absl::MutexLock l(InitFlagIfNecessary());
@ -95,18 +94,18 @@ class Flag final : public flags_internal::CommandLineFlag {
InvokeCallback();
}
void InvokeCallback() override
EXCLUSIVE_LOCKS_REQUIRED(this->locks->primary_mu) {
flags_internal::InvokeCallback(&this->locks->primary_mu,
&this->locks->callback_mu, callback_);
ABSL_EXCLUSIVE_LOCKS_REQUIRED(locks_->primary_mu) {
flags_internal::InvokeCallback(&locks_->primary_mu, &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);
if (cur_) Delete(op_, cur_);
if (def_) Delete(op_, def_);
delete this->locks;
delete locks_;
}
// Flag's data

View file

@ -25,7 +25,7 @@ namespace flags_internal {
ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit);
ABSL_CONST_INIT static std::string* program_name
GUARDED_BY(program_name_guard) = nullptr;
ABSL_GUARDED_BY(program_name_guard) = nullptr;
std::string ProgramInvocationName() {
absl::MutexLock l(&program_name_guard);

View file

@ -54,8 +54,8 @@ class FlagRegistry {
// Store a flag in this registry. Takes ownership of *flag.
void RegisterFlag(CommandLineFlag* flag);
void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); }
void Unlock() UNLOCK_FUNCTION(lock_) { lock_.Unlock(); }
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); }
void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); }
// Returns the flag object for the specified name, or nullptr if not found.
// Will emit a warning if a 'retired' flag is specified.
@ -118,7 +118,7 @@ void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
(flag->IsRetired() ? old_flag->Filename() : flag->Filename()),
"'."),
true);
} else if (flag->op != old_flag->op) {
} else if (flag->op_ != old_flag->op_) {
flags_internal::ReportUsageError(
absl::StrCat("Flag '", flag->Name(),
"' was defined more than once but with "
@ -208,16 +208,16 @@ class FlagSaverImpl {
if (flag->IsRetired()) return;
saved.name = flag->Name();
saved.op = flag->op;
saved.marshalling_op = flag->marshalling_op;
saved.op = flag->op_;
saved.marshalling_op = flag->marshalling_op_;
{
absl::MutexLock l(flag->InitFlagIfNecessary());
saved.validator = flag->GetValidator();
saved.modified = flag->modified;
saved.on_command_line = flag->on_command_line;
saved.current = Clone(saved.op, flag->cur);
saved.default_value = Clone(saved.op, flag->def);
saved.counter = flag->counter;
saved.modified = flag->modified_;
saved.on_command_line = flag->on_command_line_;
saved.current = Clone(saved.op, flag->cur_);
saved.default_value = Clone(saved.op, flag->def_);
saved.counter = flag->counter_;
}
backup_registry_.push_back(saved);
});
@ -237,26 +237,28 @@ class FlagSaverImpl {
bool restored = false;
{
absl::MutexLock l(flag->InitFlagIfNecessary());
// This function encapsulate the lock.
flag->SetValidator(src.validator);
flag->modified = src.modified;
flag->on_command_line = src.on_command_line;
if (flag->counter != src.counter ||
ChangedDirectly(flag, src.default_value, flag->def)) {
absl::MutexLock l(flag->InitFlagIfNecessary());
flag->modified_ = src.modified;
flag->on_command_line_ = src.on_command_line;
if (flag->counter_ != src.counter ||
ChangedDirectly(flag, src.default_value, flag->def_)) {
restored = true;
Copy(src.op, src.default_value, flag->def);
Copy(src.op, src.default_value, flag->def_);
}
if (flag->counter != src.counter ||
ChangedDirectly(flag, src.current, flag->cur)) {
if (flag->counter_ != src.counter ||
ChangedDirectly(flag, src.current, flag->cur_)) {
restored = true;
Copy(src.op, src.current, flag->cur);
Copy(src.op, src.current, flag->cur_);
UpdateCopy(flag);
flag->InvokeCallback();
}
}
if (restored) {
flag->counter++;
flag->counter_++;
// Revalidate the flag because the validator might store state based
// on the flag's value, which just changed due to the restore.
@ -307,44 +309,6 @@ FlagSaver::~FlagSaver() {
delete impl_;
}
// --------------------------------------------------------------------
// GetAllFlags()
// The main way the FlagRegistry class exposes its data. This
// returns, as strings, all the info about all the flags in
// the main registry, sorted first by filename they are defined
// in, and then by flagname.
// --------------------------------------------------------------------
struct FilenameFlagnameLess {
bool operator()(const CommandLineFlagInfo& a,
const CommandLineFlagInfo& b) const {
int cmp = absl::string_view(a.filename).compare(b.filename);
if (cmp != 0) return cmp < 0;
return a.name < b.name;
}
};
void FillCommandLineFlagInfo(CommandLineFlag* flag,
CommandLineFlagInfo* result) {
result->name = std::string(flag->Name());
result->type = std::string(flag->Typename());
result->description = flag->Help();
result->filename = flag->Filename();
if (!flag->IsAbseilFlag()) {
if (!flag->IsModified() && ChangedDirectly(flag, flag->cur, flag->def)) {
flag->modified = true;
}
}
result->current_value = flag->CurrentValue();
result->default_value = flag->DefaultValue();
result->is_default = !flag->IsModified();
result->has_validator_fn = flag->HasValidatorFn();
absl::MutexLock l(flag->InitFlagIfNecessary());
result->flag_ptr = flag->IsAbseilFlag() ? nullptr : flag->cur;
}
// --------------------------------------------------------------------
CommandLineFlag* FindCommandLineFlag(absl::string_view name) {
@ -380,21 +344,6 @@ void ForEachFlag(std::function<void(CommandLineFlag*)> visitor) {
// --------------------------------------------------------------------
void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT) {
flags_internal::ForEachFlag([&](CommandLineFlag* flag) {
if (flag->IsRetired()) return;
CommandLineFlagInfo fi;
FillCommandLineFlagInfo(flag, &fi);
OUTPUT->push_back(fi);
});
// Now sort the flags, first by filename they occur in, then alphabetically
std::sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameLess());
}
// --------------------------------------------------------------------
bool RegisterCommandLineFlag(CommandLineFlag* flag) {
FlagRegistry::GlobalRegistry()->RegisterFlag(flag);
return true;
@ -406,24 +355,24 @@ namespace {
class RetiredFlagObj final : public flags_internal::CommandLineFlag {
public:
constexpr RetiredFlagObj(const char* name_arg, FlagOpFn ops,
constexpr RetiredFlagObj(const char* name, FlagOpFn ops,
FlagMarshallingOpFn marshalling_ops)
: flags_internal::CommandLineFlag(
name_arg, flags_internal::HelpText::FromStaticCString(nullptr),
/*filename_arg=*/"RETIRED", ops, marshalling_ops,
name, flags_internal::HelpText::FromStaticCString(nullptr),
/*filename=*/"RETIRED", ops, marshalling_ops,
/*initial_value_gen=*/nullptr,
/*def_arg=*/nullptr,
/*cur_arg=*/nullptr) {}
/*def=*/nullptr,
/*cur=*/nullptr) {}
private:
bool IsRetired() const override { return true; }
void Destroy() const override {
// Values are heap allocated for Retired Flags.
if (this->cur) Delete(this->op, this->cur);
if (this->def) Delete(this->op, this->def);
if (cur_) Delete(op_, cur_);
if (def_) Delete(op_, def_);
if (this->locks) delete this->locks;
if (locks_) delete locks_;
delete this;
}

View file

@ -29,33 +29,6 @@
namespace absl {
namespace flags_internal {
// CommandLineFlagInfo holds all information for a flag.
struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // DO NOT use. Use flag->IsOfType<T>() instead.
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a std::string
std::string default_value; // the default value, as a std::string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption.
// nullptr for ABSL_FLAG. A pointer to the flag's current value
// otherwise. E.g., for DEFINE_int32(foo, ...), flag_ptr will be
// &FLAGS_foo.
const void* flag_ptr;
};
//-----------------------------------------------------------------------------
void FillCommandLineFlagInfo(CommandLineFlag* flag,
CommandLineFlagInfo* result);
//-----------------------------------------------------------------------------
CommandLineFlag* FindCommandLineFlag(absl::string_view name);
CommandLineFlag* FindRetiredFlag(absl::string_view name);
@ -68,11 +41,6 @@ void ForEachFlag(std::function<void(CommandLineFlag*)> visitor);
//-----------------------------------------------------------------------------
// Store the list of all flags in *OUTPUT, sorted by file.
void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
//-----------------------------------------------------------------------------
bool RegisterCommandLineFlag(CommandLineFlag*);
//-----------------------------------------------------------------------------

View file

@ -36,30 +36,6 @@ bool GetCommandLineOption(absl::string_view name, std::string* value) {
return true;
}
bool GetCommandLineFlagInfo(absl::string_view name,
CommandLineFlagInfo* OUTPUT) {
if (name.empty()) return false;
CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name);
if (flag == nullptr || flag->IsRetired()) {
return false;
}
assert(OUTPUT);
FillCommandLineFlagInfo(flag, OUTPUT);
return true;
}
CommandLineFlagInfo GetCommandLineFlagInfoOrDie(absl::string_view name) {
CommandLineFlagInfo info;
if (!GetCommandLineFlagInfo(name, &info)) {
ABSL_INTERNAL_LOG(FATAL, absl::StrCat("Flag '", name, "' does not exist"));
}
return info;
}
// --------------------------------------------------------------------
bool SetCommandLineOption(absl::string_view name, absl::string_view value) {
return SetCommandLineOptionWithMode(name, value,
flags_internal::SET_FLAGS_VALUE);

View file

@ -32,17 +32,6 @@ namespace flags_internal {
// Thread-safe.
bool GetCommandLineOption(absl::string_view name, std::string* value);
// If a flag named "name" exists, store its information in *OUTPUT
// and return true. Else return false without changing *OUTPUT.
// Thread-safe.
bool GetCommandLineFlagInfo(absl::string_view name,
CommandLineFlagInfo* OUTPUT);
// Returns the CommandLineFlagInfo of the flagname. exit() with an
// error code if name not found.
// Thread-safe.
CommandLineFlagInfo GetCommandLineFlagInfoOrDie(absl::string_view name);
// Set the value of the flag named "name" to value. If successful,
// returns true. If not successful (e.g., the flag was not found or
// the value is not a valid value), returns false.

View file

@ -44,11 +44,11 @@ namespace {
ABSL_CONST_INIT absl::Mutex processing_checks_guard(absl::kConstInit);
ABSL_CONST_INIT bool flagfile_needs_processing
GUARDED_BY(processing_checks_guard) = false;
ABSL_GUARDED_BY(processing_checks_guard) = false;
ABSL_CONST_INIT bool fromenv_needs_processing
GUARDED_BY(processing_checks_guard) = false;
ABSL_GUARDED_BY(processing_checks_guard) = false;
ABSL_CONST_INIT bool tryfromenv_needs_processing
GUARDED_BY(processing_checks_guard) = false;
ABSL_GUARDED_BY(processing_checks_guard) = false;
} // namespace
} // namespace flags_internal

View file

@ -24,7 +24,7 @@ namespace flags_internal {
namespace {
ABSL_CONST_INIT absl::Mutex usage_message_guard(absl::kConstInit);
ABSL_CONST_INIT std::string* program_usage_message
GUARDED_BY(usage_message_guard) = nullptr;
ABSL_GUARDED_BY(usage_message_guard) = nullptr;
} // namespace
} // namespace flags_internal

View file

@ -94,7 +94,7 @@ std::string NormalizeFilename(absl::string_view filename) {
ABSL_CONST_INIT absl::Mutex custom_usage_config_guard(absl::kConstInit);
ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config
GUARDED_BY(custom_usage_config_guard) = nullptr;
ABSL_GUARDED_BY(custom_usage_config_guard) = nullptr;
} // namespace