| Index: base/lazy_instance.cc
|
| diff --git a/base/lazy_instance.cc b/base/lazy_instance.cc
|
| index 1be34883a77b24563f2e8633a1d9729baa01533f..a81cb8c2d073cd331eb580488bbaf80329adbecc 100644
|
| --- a/base/lazy_instance.cc
|
| +++ b/base/lazy_instance.cc
|
| @@ -11,15 +11,18 @@
|
| #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
|
|
|
| namespace base {
|
| -
|
| -bool LazyInstanceHelper::NeedsInstance() {
|
| - // Try to create the instance, if we're the first, will go from EMPTY
|
| - // to CREATING, otherwise we've already been beaten here.
|
| - // The memory access has no memory ordering as STATE_EMPTY and STATE_CREATING
|
| - // has no associated data (memory barriers are all about ordering
|
| - // of memory accesses to *associated* data).
|
| - if (base::subtle::NoBarrier_CompareAndSwap(
|
| - &state_, STATE_EMPTY, STATE_CREATING) == STATE_EMPTY)
|
| +namespace internal {
|
| +
|
| +// TODO(joth): This function could be shared with Singleton, in place of its
|
| +// WaitForInstance() call.
|
| +bool NeedsLazyInstance(subtle::AtomicWord* state) {
|
| + // Try to create the instance, if we're the first, will go from 0 to
|
| + // kLazyInstanceStateCreating, otherwise we've already been beaten here.
|
| + // The memory access has no memory ordering as state 0 and
|
| + // kLazyInstanceStateCreating have no associated data (memory barriers are
|
| + // all about ordering of memory accesses to *associated* data).
|
| + if (subtle::NoBarrier_CompareAndSwap(state, 0,
|
| + kLazyInstanceStateCreating) == 0)
|
| // Caller must create instance
|
| return true;
|
|
|
| @@ -27,29 +30,30 @@ bool LazyInstanceHelper::NeedsInstance() {
|
| // The load has acquire memory ordering as a thread which sees
|
| // state_ == STATE_CREATED needs to acquire visibility over
|
| // the associated data (buf_). Pairing Release_Store is in
|
| - // CompleteInstance().
|
| - while (base::subtle::Acquire_Load(&state_) != STATE_CREATED)
|
| + // CompleteLazyInstance().
|
| + while (subtle::Acquire_Load(state) == kLazyInstanceStateCreating) {
|
| PlatformThread::YieldCurrentThread();
|
| -
|
| + }
|
| // Someone else created the instance.
|
| return false;
|
| }
|
|
|
| -void LazyInstanceHelper::CompleteInstance(void* instance, void (*dtor)(void*)) {
|
| +void CompleteLazyInstance(subtle::AtomicWord* state,
|
| + subtle::AtomicWord new_instance,
|
| + void* lazy_instance,
|
| + void (*dtor)(void*)) {
|
| // See the comment to the corresponding HAPPENS_AFTER in Pointer().
|
| - ANNOTATE_HAPPENS_BEFORE(&state_);
|
| + ANNOTATE_HAPPENS_BEFORE(state);
|
|
|
| // Instance is created, go from CREATING to CREATED.
|
| - // Releases visibility over buf_ to readers. Pairing Acquire_Load's are in
|
| - // NeedsInstance() and Pointer().
|
| - base::subtle::Release_Store(&state_, STATE_CREATED);
|
| + // Releases visibility over private_buf_ to readers. Pairing Acquire_Load's
|
| + // are in NeedsInstance() and Pointer().
|
| + subtle::Release_Store(state, new_instance);
|
|
|
| // Make sure that the lazily instantiated object will get destroyed at exit.
|
| if (dtor)
|
| - base::AtExitManager::RegisterCallback(dtor, instance);
|
| + AtExitManager::RegisterCallback(dtor, lazy_instance);
|
| }
|
|
|
| +} // namespace internal
|
| } // namespace base
|
| -
|
| -
|
| -
|
|
|