| Index: base/singleton.h
|
| ===================================================================
|
| --- base/singleton.h (revision 18944)
|
| +++ base/singleton.h (working copy)
|
| @@ -7,6 +7,7 @@
|
|
|
| #include "base/at_exit.h"
|
| #include "base/atomicops.h"
|
| +#include "base/dynamic_annotations.h"
|
| #include "base/platform_thread.h"
|
|
|
| // Default traits for Singleton<Type>. Calls operator new and operator delete on
|
| @@ -116,8 +117,11 @@
|
| static const base::subtle::AtomicWord kBeingCreatedMarker = 1;
|
|
|
| base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_);
|
| - if (value != 0 && value != kBeingCreatedMarker)
|
| + if (value != 0 && value != kBeingCreatedMarker) {
|
| + // See the corresponding HAPPENS_BEFORE below.
|
| + ANNOTATE_HAPPENS_AFTER(&instance_);
|
| return reinterpret_cast<Type*>(value);
|
| + }
|
|
|
| // Object isn't created yet, maybe we will get to create it, let's try...
|
| if (base::subtle::Acquire_CompareAndSwap(&instance_,
|
| @@ -127,6 +131,11 @@
|
| // will ever get here. Threads might be spinning on us, and they will
|
| // stop right after we do this store.
|
| Type* newval = Traits::New();
|
| +
|
| + // This annotation helps race detectors recognize correct lock-less
|
| + // synchronization between different threads calling get().
|
| + // See the corresponding HAPPENS_AFTER below and above.
|
| + ANNOTATE_HAPPENS_BEFORE(&instance_);
|
| base::subtle::Release_Store(
|
| &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval));
|
|
|
| @@ -150,6 +159,8 @@
|
| PlatformThread::YieldCurrentThread();
|
| }
|
|
|
| + // See the corresponding HAPPENS_BEFORE above.
|
| + ANNOTATE_HAPPENS_AFTER(&instance_);
|
| return reinterpret_cast<Type*>(value);
|
| }
|
|
|
|
|