security/sandbox/chromium/base/lazy_instance.cc

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #include "base/lazy_instance.h"
michael@0 6
michael@0 7 #include "base/at_exit.h"
michael@0 8 #include "base/atomicops.h"
michael@0 9 #include "base/basictypes.h"
michael@0 10 #include "base/threading/platform_thread.h"
michael@0 11 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
michael@0 12
michael@0 13 namespace base {
michael@0 14 namespace internal {
michael@0 15
michael@0 16 // TODO(joth): This function could be shared with Singleton, in place of its
michael@0 17 // WaitForInstance() call.
michael@0 18 bool NeedsLazyInstance(subtle::AtomicWord* state) {
michael@0 19 // Try to create the instance, if we're the first, will go from 0 to
michael@0 20 // kLazyInstanceStateCreating, otherwise we've already been beaten here.
michael@0 21 // The memory access has no memory ordering as state 0 and
michael@0 22 // kLazyInstanceStateCreating have no associated data (memory barriers are
michael@0 23 // all about ordering of memory accesses to *associated* data).
michael@0 24 if (subtle::NoBarrier_CompareAndSwap(state, 0,
michael@0 25 kLazyInstanceStateCreating) == 0)
michael@0 26 // Caller must create instance
michael@0 27 return true;
michael@0 28
michael@0 29 // It's either in the process of being created, or already created. Spin.
michael@0 30 // The load has acquire memory ordering as a thread which sees
michael@0 31 // state_ == STATE_CREATED needs to acquire visibility over
michael@0 32 // the associated data (buf_). Pairing Release_Store is in
michael@0 33 // CompleteLazyInstance().
michael@0 34 while (subtle::Acquire_Load(state) == kLazyInstanceStateCreating) {
michael@0 35 PlatformThread::YieldCurrentThread();
michael@0 36 }
michael@0 37 // Someone else created the instance.
michael@0 38 return false;
michael@0 39 }
michael@0 40
michael@0 41 void CompleteLazyInstance(subtle::AtomicWord* state,
michael@0 42 subtle::AtomicWord new_instance,
michael@0 43 void* lazy_instance,
michael@0 44 void (*dtor)(void*)) {
michael@0 45 // See the comment to the corresponding HAPPENS_AFTER in Pointer().
michael@0 46 ANNOTATE_HAPPENS_BEFORE(state);
michael@0 47
michael@0 48 // Instance is created, go from CREATING to CREATED.
michael@0 49 // Releases visibility over private_buf_ to readers. Pairing Acquire_Load's
michael@0 50 // are in NeedsInstance() and Pointer().
michael@0 51 subtle::Release_Store(state, new_instance);
michael@0 52
michael@0 53 // Make sure that the lazily instantiated object will get destroyed at exit.
michael@0 54 if (dtor)
michael@0 55 AtExitManager::RegisterCallback(dtor, lazy_instance);
michael@0 56 }
michael@0 57
michael@0 58 } // namespace internal
michael@0 59 } // namespace base

mercurial