summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-15 21:50:36 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-15 21:50:36 +0000
commit94b555ee6cb66836bae146d9995aed6eb8c4a2c0 (patch)
tree872ebc8da85acd149c019ea6c39ee0b943951213 /base
parentc0fb15fb4e0f8b1bad566e4e6f53fd7df0a5cb12 (diff)
downloadchromium_src-94b555ee6cb66836bae146d9995aed6eb8c4a2c0.zip
chromium_src-94b555ee6cb66836bae146d9995aed6eb8c4a2c0.tar.gz
chromium_src-94b555ee6cb66836bae146d9995aed6eb8c4a2c0.tar.bz2
Reduce race potential for lazy testing initialization of profiler
Initialization of the profiler is supposed to happen while single threaded. The tests however often skip affirmative initialization, and rely on lazy initialization. This CL tightens up that process, to reduce changes of races (even benign races) during testing. I also added a suppression for examination of the state, which is always a benign race. At initialization time we rely on a lock (now) to ensure race freedom (if we get a racy value of state). r=rtenneti Review URL: http://codereview.chromium.org/8570007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110180 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/tracked_objects.cc31
1 files changed, 23 insertions, 8 deletions
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc
index 737c2b3..39056d6 100644
--- a/base/tracked_objects.cc
+++ b/base/tracked_objects.cc
@@ -583,19 +583,34 @@ bool ThreadData::Initialize() {
if (!kTrackAllTaskObjects)
return false; // Not compiled in.
if (status_ != UNINITIALIZED)
- return true;
- // Initialize all leaking constants that are difficult to toggle in and out
- // of existance.
- // First call must be made when single threaded at startup.
+ return true; // Someone else did the initialization.
+ // Due to racy lazy initialization in tests, we'll need to recheck status_
+ // after we acquire the lock.
+
+ // Ensure that we don't double initialize tls. We are called when single
+ // threaded in the product, but some tests may be racy and lazy about our
+ // initialization.
+ base::AutoLock lock(*list_lock_.Pointer());
+ if (status_ != UNINITIALIZED)
+ return true; // Someone raced in here and beat us.
+
// Perform the "real" TLS initialization now, and leave it intact through
// process termination.
- if (!tls_index_.initialized()) // Testing may have initialized this.
+ if (!tls_index_.initialized()) { // Testing may have initialized this.
tls_index_.Initialize(&ThreadData::OnThreadTermination);
- DCHECK(tls_index_.initialized());
- status_ = kInitialStartupState;
+ if (!tls_index_.initialized())
+ return false;
+ }
- base::AutoLock lock(*list_lock_.Pointer());
+ // Incarnation counter is only significant to testing, as it otherwise will
+ // never again change in this process.
++incarnation_counter_;
+
+ // The lock is not critical for setting status_, but it doesn't hurt. It also
+ // ensures that if we have a racy initialization, that we'll bail as soon as
+ // we get the lock earlier in this method.
+ status_ = kInitialStartupState;
+ DCHECK(status_ != UNINITIALIZED);
return true;
}