| Index: base/tracked_objects.cc
|
| ===================================================================
|
| --- base/tracked_objects.cc (revision 110116)
|
| +++ base/tracked_objects.cc (working copy)
|
| @@ -583,19 +583,34 @@
|
| 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;
|
| }
|
|
|
|
|