13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/lazy_instance.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/at_exit.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/atomicops.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/platform_thread.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool LazyInstanceHelper::NeedsInstance() { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Try to create the instance, if we're the first, will go from EMPTY 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to CREATING, otherwise we've already been beaten here. 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (base::subtle::Acquire_CompareAndSwap( 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &state_, STATE_EMPTY, STATE_CREATING) == STATE_EMPTY) { 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Caller must create instance 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // It's either in the process of being created, or already created. Spin. 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PlatformThread::YieldCurrentThread(); 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Someone else created the instance. 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid LazyInstanceHelper::CompleteInstance(void* instance, void (*dtor)(void*)) { 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See the comment to the corresponding HAPPENS_AFTER in Pointer(). 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ANNOTATE_HAPPENS_BEFORE(&state_); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Instance is created, go from CREATING to CREATED. 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::subtle::Release_Store(&state_, STATE_CREATED); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure that the lazily instantiated object will get destroyed at exit. 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (dtor) 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::AtExitManager::RegisterCallback(dtor, instance); 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 45