diff options
-rw-r--r-- | base/tracked_objects.cc | 4 | ||||
-rw-r--r-- | base/tracked_objects.h | 27 |
2 files changed, 28 insertions, 3 deletions
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc index a51c0da..bc259a2 100644 --- a/base/tracked_objects.cc +++ b/base/tracked_objects.cc @@ -18,6 +18,10 @@ namespace tracked_objects { // static TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); +// A global state variable to prevent repeated initialization during tests. +// static +AutoTracking::State AutoTracking::state_ = AutoTracking::kNeverBeenRun; + //------------------------------------------------------------------------------ // Death data tallies durations when a death takes place. diff --git a/base/tracked_objects.h b/base/tracked_objects.h index 4d63997..48e2b5a 100644 --- a/base/tracked_objects.h +++ b/base/tracked_objects.h @@ -654,24 +654,45 @@ class ThreadData { //------------------------------------------------------------------------------ // Provide simple way to to start global tracking, and to tear down tracking // when done. Note that construction and destruction of this object must be -// done when running in single threaded mode (before spawning a lot of threads +// done when running in threaded mode (before spawning a lot of threads // for construction, and after shutting down all the threads for destruction). +// To prevent grabbing thread local store resources time and again if someone +// chooses to try to re-run the browser many times, we maintain global state and +// only allow the tracking system to be started up at most once, and shutdown +// at most once. See bug 31344 for an example. + class AutoTracking { public: - AutoTracking() { ThreadData::StartTracking(true); } + AutoTracking() { + if (state_ != kNeverBeenRun) + return; + ThreadData::StartTracking(true); + state_ = kRunning; + } ~AutoTracking() { -#ifndef NDEBUG // Don't call these in a Release build: they just waste time. +#ifndef NDEBUG + if (state_ != kRunning) + return; + // Don't call these in a Release build: they just waste time. // The following should ONLY be called when in single threaded mode. It is // unsafe to do this cleanup if other threads are still active. // It is also very unnecessary, so I'm only doing this in debug to satisfy // purify (if we need to!). ThreadData::ShutdownSingleThreadedCleanup(); + state_ = kTornDownAndStopped; #endif } private: + enum State { + kNeverBeenRun, + kRunning, + kTornDownAndStopped, + }; + static State state_; + DISALLOW_COPY_AND_ASSIGN(AutoTracking); }; |