Commit 1366baf8 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

let SingletonVault::type_ be atomic

Summary: It is possible to have concurrent calls to `SingletonVault::setType` and `SingletonHolder::createInstance`. In which cases, non-atomic accesses to `SingletonVault::type_` race.

Differential Revision: D27904167

fbshipit-source-id: be01ee375d37839629b2e1d64bec99e32cd7e213
parent 549f235f
......@@ -279,7 +279,8 @@ void SingletonHolder<T>::createInstance() {
creating_thread_.store(std::this_thread::get_id(), std::memory_order_release);
auto state = vault_.state_.rlock();
if (vault_.type_ != SingletonVault::Type::Relaxed &&
if (vault_.type_.load(std::memory_order_relaxed) !=
SingletonVault::Type::Relaxed &&
!state->registrationComplete) {
detail::singletonWarnCreateBeforeRegistrationCompleteAndAbort(type());
}
......
......@@ -239,7 +239,8 @@ void SingletonVault::registerSingleton(detail::SingletonHolderBase* entry) {
auto state = state_.rlock();
state->check(detail::SingletonVaultState::Type::Running);
if (UNLIKELY(state->registrationComplete) && type_ == Type::Strict) {
if (UNLIKELY(state->registrationComplete) &&
type_.load(std::memory_order_relaxed) == Type::Strict) {
LOG(ERROR) << "Registering singleton after registrationComplete().";
}
......@@ -252,7 +253,8 @@ void SingletonVault::addEagerInitSingleton(detail::SingletonHolderBase* entry) {
auto state = state_.rlock();
state->check(detail::SingletonVaultState::Type::Running);
if (UNLIKELY(state->registrationComplete) && type_ == Type::Strict) {
if (UNLIKELY(state->registrationComplete) &&
type_.load(std::memory_order_relaxed) == Type::Strict) {
LOG(ERROR) << "Registering for eager-load after registrationComplete().";
}
......@@ -273,7 +275,7 @@ void SingletonVault::registrationComplete() {
}
auto singletons = singletons_.rlock();
if (type_ == Type::Strict) {
if (type_.load(std::memory_order_relaxed) == Type::Strict) {
for (const auto& p : *singletons) {
if (p.second->hasLiveInstance()) {
throw std::runtime_error(
......
......@@ -505,7 +505,7 @@ class SingletonVault {
return &detail::createGlobal<SingletonVault, VaultTag>();
}
void setType(Type type) { type_ = type; }
void setType(Type type) { type_.store(type, std::memory_order_relaxed); }
void setShutdownTimeout(std::chrono::milliseconds shutdownTimeout) {
shutdownTimeout_ = shutdownTimeout;
......@@ -565,7 +565,7 @@ class SingletonVault {
// destroyInstances().
Synchronized<detail::SingletonVaultState, SharedMutexReadPriority> state_;
Type type_;
std::atomic<Type> type_;
std::atomic<bool> shutdownTimerStarted_{false};
std::chrono::milliseconds shutdownTimeout_{std::chrono::minutes{5}};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment