summaryrefslogtreecommitdiffstats
path: root/base/lazy_instance.cc
diff options
context:
space:
mode:
authorcraig.schlenter@chromium.org <craig.schlenter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 15:28:48 +0000
committercraig.schlenter@chromium.org <craig.schlenter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 15:28:48 +0000
commitc1aeaac2015e93e1168453d4de29619c43fda669 (patch)
tree062ebdcfdcca6b6f8c781ede55b5dc7d97e8f142 /base/lazy_instance.cc
parentdc99ca7f7328d14d43af2fd5b8cde944c6a08054 (diff)
downloadchromium_src-c1aeaac2015e93e1168453d4de29619c43fda669.zip
chromium_src-c1aeaac2015e93e1168453d4de29619c43fda669.tar.gz
chromium_src-c1aeaac2015e93e1168453d4de29619c43fda669.tar.bz2
Avoid a strict aliasing issue in LazyInstance.
The key change here is to use the return value from placement new rather than casting buf_. Avoiding the cast avoids the strict aliasing issue. BUG=28749 Review URL: http://codereview.chromium.org/548011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41434 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/lazy_instance.cc')
-rw-r--r--base/lazy_instance.cc43
1 files changed, 23 insertions, 20 deletions
diff --git a/base/lazy_instance.cc b/base/lazy_instance.cc
index 9923253..565ad1f 100644
--- a/base/lazy_instance.cc
+++ b/base/lazy_instance.cc
@@ -12,35 +12,38 @@
namespace base {
-void LazyInstanceHelper::EnsureInstance(void* instance,
- void (*ctor)(void*),
- void (*dtor)(void*)) {
+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.
if (base::subtle::Acquire_CompareAndSwap(
&state_, STATE_EMPTY, STATE_CREATING) == STATE_EMPTY) {
- // Created the instance in the space provided by |instance|.
- ctor(instance);
-
- // See the comment to the corresponding HAPPENS_AFTER in Pointer().
- ANNOTATE_HAPPENS_BEFORE(&state_);
-
- // Instance is created, go from CREATING to CREATED.
- base::subtle::Release_Store(&state_, STATE_CREATED);
-
- // Allow reusing the LazyInstance (reset it to the initial state). This
- // makes possible calling all AtExit callbacks between tests. Assumes that
- // no other threads execute when AtExit callbacks are processed.
- base::AtExitManager::RegisterCallback(&LazyInstanceHelper::ResetState,
- this);
-
- // Make sure that the lazily instantiated object will get destroyed at exit.
- base::AtExitManager::RegisterCallback(dtor, instance);
+ // Caller must create instance
+ return true;
} else {
// It's either in the process of being created, or already created. Spin.
while (base::subtle::NoBarrier_Load(&state_) != STATE_CREATED)
PlatformThread::YieldCurrentThread();
}
+
+ // Someone else created the instance.
+ return false;
+}
+
+void LazyInstanceHelper::CompleteInstance(void* instance, void (*dtor)(void*)) {
+ // See the comment to the corresponding HAPPENS_AFTER in Pointer().
+ ANNOTATE_HAPPENS_BEFORE(&state_);
+
+ // Instance is created, go from CREATING to CREATED.
+ base::subtle::Release_Store(&state_, STATE_CREATED);
+
+ // Allow reusing the LazyInstance (reset it to the initial state). This
+ // makes possible calling all AtExit callbacks between tests. Assumes that
+ // no other threads execute when AtExit callbacks are processed.
+ base::AtExitManager::RegisterCallback(&LazyInstanceHelper::ResetState,
+ this);
+
+ // Make sure that the lazily instantiated object will get destroyed at exit.
+ base::AtExitManager::RegisterCallback(dtor, instance);
}
// static