diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 21:50:36 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 21:50:36 +0000 |
commit | 94b555ee6cb66836bae146d9995aed6eb8c4a2c0 (patch) | |
tree | 872ebc8da85acd149c019ea6c39ee0b943951213 /base | |
parent | c0fb15fb4e0f8b1bad566e4e6f53fd7df0a5cb12 (diff) | |
download | chromium_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.cc | 31 |
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; } |