diff options
author | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-20 11:51:28 +0000 |
---|---|---|
committer | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-20 11:51:28 +0000 |
commit | 87738f7d5cdb54e524520144f28baa78e38098e2 (patch) | |
tree | 3c1db8b038a88450c85a4703b5f399ad9e23f942 | |
parent | a077da7b45007de882a8d843ad084ff2eba14c2f (diff) | |
download | chromium_src-87738f7d5cdb54e524520144f28baa78e38098e2.zip chromium_src-87738f7d5cdb54e524520144f28baa78e38098e2.tar.gz chromium_src-87738f7d5cdb54e524520144f28baa78e38098e2.tar.bz2 |
Revert 211956 "base: Change WeakPtr to use SequenceChecker inste..."
As well as revert 212725 "base: Make SequenceChecker death tests multi-threads work correctly."
See http://crbug.com/261448
> base: Change WeakPtr to use SequenceChecker instead of ThreadChecker.
>
> This will enable WeakPtr to be used in SequencedWorkerPool, et al. with a sequence token.
>
> This is a continuation of issue: https://chromiumcodereview.appspot.com/18231002/
>
> The original issue got messed up by a rietveld bug, so refer there for history and comments.
>
> BUG=165590
>
> Review URL: https://chromiumcodereview.appspot.com/18501008
TBR=tommycli@chromium.org
Review URL: https://chromiumcodereview.appspot.com/19695005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212780 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/base.gyp | 1 | ||||
-rw-r--r-- | base/memory/weak_ptr.cc | 12 | ||||
-rw-r--r-- | base/memory/weak_ptr.h | 6 | ||||
-rw-r--r-- | base/message_loop/message_pump_io_ios.h | 1 | ||||
-rw-r--r-- | base/sequence_checker.h | 16 | ||||
-rw-r--r-- | base/sequence_checker_impl.cc | 39 | ||||
-rw-r--r-- | base/sequence_checker_impl.h | 42 | ||||
-rw-r--r-- | base/sequence_checker_impl_unittest.cc | 218 | ||||
-rw-r--r-- | base/sequence_checker_unittest.cc | 338 | ||||
-rw-r--r-- | chrome/browser/storage_monitor/storage_monitor.h | 1 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_ms.h | 1 | ||||
-rw-r--r-- | remoting/host/audio_capturer_win.h | 1 | ||||
-rw-r--r-- | tools/valgrind/gtest_exclude/base_unittests.gtest.txt | 4 |
13 files changed, 296 insertions, 384 deletions
diff --git a/base/base.gyp b/base/base.gyp index 972ff3c..56a036a 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -570,6 +570,7 @@ 'scoped_observer.h', 'security_unittest.cc', 'sequence_checker_unittest.cc', + 'sequence_checker_impl_unittest.cc', 'sha1_unittest.cc', 'stl_util_unittest.cc', 'strings/nullable_string16_unittest.cc', diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc index d9ce86a..a22f61a 100644 --- a/base/memory/weak_ptr.cc +++ b/base/memory/weak_ptr.cc @@ -10,21 +10,21 @@ namespace internal { WeakReference::Flag::Flag() : is_valid_(true) { // Flags only become bound when checked for validity, or invalidated, // so that we can check that later validity/invalidation operations on - // the same Flag take place on the same sequenced thread. - sequence_checker_.DetachFromSequence(); + // the same Flag take place on the same thread. + thread_checker_.DetachFromThread(); } void WeakReference::Flag::Invalidate() { // The flag being invalidated with a single ref implies that there are no // weak pointers in existence. Allow deletion on other thread in this case. - DCHECK(sequence_checker_.CalledOnValidSequencedThread() || HasOneRef()) - << "WeakPtrs must be invalidated on the same sequenced thread."; + DCHECK(thread_checker_.CalledOnValidThread() || HasOneRef()) + << "WeakPtrs must be checked and invalidated on the same thread."; is_valid_ = false; } bool WeakReference::Flag::IsValid() const { - DCHECK(sequence_checker_.CalledOnValidSequencedThread()) - << "WeakPtrs must be checked on the same sequenced thread."; + DCHECK(thread_checker_.CalledOnValidThread()) + << "WeakPtrs must be checked and invalidated on the same thread."; return is_valid_; } diff --git a/base/memory/weak_ptr.h b/base/memory/weak_ptr.h index b4120a1..621c0fa 100644 --- a/base/memory/weak_ptr.h +++ b/base/memory/weak_ptr.h @@ -67,8 +67,8 @@ #include "base/base_export.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/sequence_checker.h" #include "base/template_util.h" +#include "base/threading/thread_checker.h" namespace base { @@ -91,14 +91,14 @@ class BASE_EXPORT WeakReference { bool IsValid() const; // Remove this when crbug.com/234964 is addressed. - void DetachFromThreadHack() { sequence_checker_.DetachFromSequence(); } + void DetachFromThreadHack() { thread_checker_.DetachFromThread(); } private: friend class base::RefCountedThreadSafe<Flag>; ~Flag(); - SequenceChecker sequence_checker_; + ThreadChecker thread_checker_; bool is_valid_; }; diff --git a/base/message_loop/message_pump_io_ios.h b/base/message_loop/message_pump_io_ios.h index 6779aab..6596862b 100644 --- a/base/message_loop/message_pump_io_ios.h +++ b/base/message_loop/message_pump_io_ios.h @@ -11,7 +11,6 @@ #include "base/memory/ref_counted.h" #include "base/message_loop/message_pump_mac.h" #include "base/observer_list.h" -#include "base/threading/thread_checker.h" namespace base { diff --git a/base/sequence_checker.h b/base/sequence_checker.h index 89bbd7e..fbf146a 100644 --- a/base/sequence_checker.h +++ b/base/sequence_checker.h @@ -28,11 +28,12 @@ class SequencedTaskRunner; // the right version for your build configuration. class SequenceCheckerDoNothing { public: - bool CalledOnValidSequencedThread() const { + bool CalledOnValidSequence() const { return true; } - void DetachFromSequence() {} + void ChangeSequence( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) {} }; // SequenceChecker is a helper class used to help verify that some @@ -43,6 +44,10 @@ class SequenceCheckerDoNothing { // Example: // class MyClass { // public: +// explicit MyClass( +// const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) +// : sequence_checker_(sequenced_task_runner) {} +// // void Foo() { // DCHECK(sequence_checker_.CalledOnValidSequence()); // ... (do stuff) ... @@ -55,9 +60,16 @@ class SequenceCheckerDoNothing { // In Release mode, CalledOnValidSequence will always return true. #if ENABLE_SEQUENCE_CHECKER class SequenceChecker : public SequenceCheckerImpl { + public: + explicit SequenceChecker( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) + : SequenceCheckerImpl(sequenced_task_runner) {} }; #else class SequenceChecker : public SequenceCheckerDoNothing { + public: + explicit SequenceChecker( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) {} }; #endif // ENABLE_SEQUENCE_CHECKER diff --git a/base/sequence_checker_impl.cc b/base/sequence_checker_impl.cc index e95b8ee..24d9ed9 100644 --- a/base/sequence_checker_impl.cc +++ b/base/sequence_checker_impl.cc @@ -4,43 +4,28 @@ #include "base/sequence_checker_impl.h" +#include "base/sequenced_task_runner.h" + namespace base { -SequenceCheckerImpl::SequenceCheckerImpl() - : sequence_token_assigned_(false) { - AutoLock auto_lock(lock_); - EnsureSequenceTokenAssigned(); -} +SequenceCheckerImpl::SequenceCheckerImpl( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) + : sequenced_task_runner_(sequenced_task_runner) {} SequenceCheckerImpl::~SequenceCheckerImpl() {} -bool SequenceCheckerImpl::CalledOnValidSequencedThread() const { +bool SequenceCheckerImpl::CalledOnValidSequence() const { AutoLock auto_lock(lock_); - EnsureSequenceTokenAssigned(); - - // If this thread is not associated with a SequencedWorkerPool, - // SequenceChecker behaves as a ThreadChecker. See header for details. - if (!sequence_token_.IsValid()) - return thread_checker_.CalledOnValidThread(); - - return sequence_token_.Equals( - SequencedWorkerPool::GetSequenceTokenForCurrentThread()); + return sequenced_task_runner_.get() ? + sequenced_task_runner_->RunsTasksOnCurrentThread() : + thread_checker_.CalledOnValidThread(); } -void SequenceCheckerImpl::DetachFromSequence() { +void SequenceCheckerImpl::ChangeSequence( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner) { AutoLock auto_lock(lock_); + sequenced_task_runner_ = sequenced_task_runner; thread_checker_.DetachFromThread(); - sequence_token_assigned_ = false; - sequence_token_ = SequencedWorkerPool::SequenceToken(); -} - -void SequenceCheckerImpl::EnsureSequenceTokenAssigned() const { - lock_.AssertAcquired(); - if (sequence_token_assigned_) - return; - - sequence_token_assigned_ = true; - sequence_token_ = SequencedWorkerPool::GetSequenceTokenForCurrentThread(); } } // namespace base diff --git a/base/sequence_checker_impl.h b/base/sequence_checker_impl.h index 741aafe..ccd1198 100644 --- a/base/sequence_checker_impl.h +++ b/base/sequence_checker_impl.h @@ -7,42 +7,48 @@ #include "base/base_export.h" #include "base/basictypes.h" +#include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_checker_impl.h" namespace base { +class SequencedTaskRunner; + // SequenceCheckerImpl is used to help verify that some methods of a // class are called in sequence -- that is, called from the same // SequencedTaskRunner. It is a generalization of ThreadChecker; in -// particular, it behaves exactly like ThreadChecker if constructed -// on a thread that is not part of a SequencedWorkerPool. +// particular, it behaves exactly like ThreadChecker if its passed a +// NULL SequencedTaskRunner. class BASE_EXPORT SequenceCheckerImpl { public: - SequenceCheckerImpl(); + // |sequenced_task_runner| can be NULL. In that case, this object + // behaves exactly like a ThreadChecker bound to the current thread, + // i.e. CalledOnValidSequence() behaves like CalledOnValidThread(). + explicit SequenceCheckerImpl( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner); ~SequenceCheckerImpl(); - // Returns whether the we are being called on the same sequence token - // as previous calls. If there is no associated sequence, then returns - // whether we are being called on the underlying ThreadChecker's thread. - bool CalledOnValidSequencedThread() const; + // Returns whether the we are being called on the underyling + // SequencedTaskRunner. If we're not bound to a + // |sequenced_task_runner|, returns whether we are being called on + // the underlying ThreadChecker's thread. + bool CalledOnValidSequence() const; - // Unbinds the checker from the currently associated sequence. The - // checker will be re-bound on the next call to CalledOnValidSequence(). - void DetachFromSequence(); + // Changes the underyling SequencedTaskRunner. + // |sequenced_task_runner| can be NULL. In that case, this object + // behaves exactly like a ThreadChecker that has been detached from + // its thread, i.e. we will be bound to the thread on which we next + // call CalledOnValidSequence(). + void ChangeSequence( + const scoped_refptr<SequencedTaskRunner>& sequenced_task_runner); private: - void EnsureSequenceTokenAssigned() const; - // Guards all variables below. mutable Lock lock_; - - // Used if |sequence_token_| is not valid. + scoped_refptr<SequencedTaskRunner> sequenced_task_runner_; + // Used if |sequenced_task_runner_| is NULL. ThreadCheckerImpl thread_checker_; - mutable bool sequence_token_assigned_; - - mutable SequencedWorkerPool::SequenceToken sequence_token_; DISALLOW_COPY_AND_ASSIGN(SequenceCheckerImpl); }; diff --git a/base/sequence_checker_impl_unittest.cc b/base/sequence_checker_impl_unittest.cc new file mode 100644 index 0000000..b05da11 --- /dev/null +++ b/base/sequence_checker_impl_unittest.cc @@ -0,0 +1,218 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/sequence_checker_impl.h" + +#include <cstddef> + +#include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/location.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop.h" +#include "base/sequenced_task_runner.h" +#include "base/threading/thread.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +namespace { + +// Implementation of SequencedTaskRunner that lets us control what +// RunsTasksOnCurrentThread() returns. +class FakeTaskRunner : public SequencedTaskRunner { + public: + FakeTaskRunner() : runs_tasks_on_current_thread_(false) {} + + void SetRunsTasksOnCurrentThread(bool runs_tasks_on_current_thread) { + runs_tasks_on_current_thread_ = runs_tasks_on_current_thread; + } + + // SequencedTaskRunner implementation. + virtual bool PostDelayedTask(const tracked_objects::Location& from_here, + const Closure& task, + TimeDelta delay) OVERRIDE { + ADD_FAILURE(); + return false; + } + + virtual bool PostNonNestableDelayedTask( + const tracked_objects::Location& from_here, + const Closure& task, + TimeDelta delay) OVERRIDE { + ADD_FAILURE(); + return false; + } + + virtual bool RunsTasksOnCurrentThread() const OVERRIDE { + return runs_tasks_on_current_thread_; + } + + protected: + virtual ~FakeTaskRunner() {} + + private: + bool runs_tasks_on_current_thread_; +}; + +class SequenceCheckerImplTest : public ::testing::Test { +}; + +// Create a SequenceCheckerImpl with a SequencedTaskRunner and make +// sure that CalledOnValidSequence() returns what that SequencedTaskRunner +// returns for RunsTasksOnCurrentThread(). +TEST_F(SequenceCheckerImplTest, CalledOnValidSequenceNonNull) { + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner( + new FakeTaskRunner()); + + const SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner); + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); + + fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(true); + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + + fake_sequenced_task_runner->SetRunsTasksOnCurrentThread(false); + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); +} + +void ExpectCalledOnValidSequence( + const tracked_objects::Location& location, + const SequenceCheckerImpl* sequence_checker_impl, + bool expected_value) { + EXPECT_EQ(expected_value, sequence_checker_impl->CalledOnValidSequence()) + << location.ToString(); +} + +// Create a SequenceCheckerImpl with no SequencedTaskRunner and make +// sure that CalledOnValidSequence() behaves like +// ThreadChecker::CalledOnValidThread(). +TEST_F(SequenceCheckerImplTest, CalledOnValidSequenceNull) { + const SequenceCheckerImpl sequence_checker_impl(NULL); + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + + { + Thread thread("thread 1"); + ASSERT_TRUE(thread.Start()); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&ExpectCalledOnValidSequence, + FROM_HERE, + Unretained(&sequence_checker_impl), + false)); + } + + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); +} + +// Create a SequenceCheckerImpl with a SequencedTaskRunner and switch +// it to another one. CalledOnValidSequence() should return what its +// underlying SequencedTaskRunner returns for +// RunsTasksOnCurrentThread(). +TEST_F(SequenceCheckerImplTest, ChangeSequenceNonNull) { + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner1( + new FakeTaskRunner()); + + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner2( + new FakeTaskRunner()); + + SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner1); + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); + + fake_sequenced_task_runner2->SetRunsTasksOnCurrentThread(true); + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); + + sequence_checker_impl.ChangeSequence(fake_sequenced_task_runner2); + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + + sequence_checker_impl.ChangeSequence(fake_sequenced_task_runner1); + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); +} + +// Create a SequenceCheckerImpl with a SequencedTaskRunner and switch +// it to a NULL one. CalledOnValidSequence() should then behave like +// ThreadChecker::CalledOnValidThread(). +TEST_F(SequenceCheckerImplTest, ChangeSequenceNull) { + const scoped_refptr<FakeTaskRunner> fake_sequenced_task_runner( + new FakeTaskRunner()); + + SequenceCheckerImpl sequence_checker_impl(fake_sequenced_task_runner); + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); + + sequence_checker_impl.ChangeSequence(NULL); + // Binds to current thread. + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + { + Thread thread("thread 1"); + ASSERT_TRUE(thread.Start()); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&ExpectCalledOnValidSequence, + FROM_HERE, + Unretained(&sequence_checker_impl), + false)); + } + + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + + sequence_checker_impl.ChangeSequence(NULL); + // Binds to worker thread. + { + Thread thread("thread 2"); + ASSERT_TRUE(thread.Start()); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&ExpectCalledOnValidSequence, + FROM_HERE, + Unretained(&sequence_checker_impl), + true)); + } + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); +} + +// Create a SequenceCheckerImpl with the current thread's task runner +// and switch it to other task runners. CalledOnValidSequence() should +// return true only when it's on the correct thread. +TEST_F(SequenceCheckerImplTest, MultipleThreads) { + MessageLoop loop; + + SequenceCheckerImpl sequence_checker_impl(loop.message_loop_proxy()); + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + + { + Thread thread("thread 1"); + ASSERT_TRUE(thread.Start()); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&ExpectCalledOnValidSequence, + FROM_HERE, + Unretained(&sequence_checker_impl), + false)); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&SequenceCheckerImpl::ChangeSequence, + Unretained(&sequence_checker_impl), + thread.message_loop_proxy())); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&ExpectCalledOnValidSequence, + FROM_HERE, + Unretained(&sequence_checker_impl), + true)); + } + + EXPECT_FALSE(sequence_checker_impl.CalledOnValidSequence()); + + sequence_checker_impl.ChangeSequence(loop.message_loop_proxy()); + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); + + { + Thread thread("thread 2"); + ASSERT_TRUE(thread.Start()); + thread.message_loop()->PostTask( + FROM_HERE, Bind(&ExpectCalledOnValidSequence, + FROM_HERE, + Unretained(&sequence_checker_impl), + false)); + } + + EXPECT_TRUE(sequence_checker_impl.CalledOnValidSequence()); +} + +} // namespace + +} // namespace base diff --git a/base/sequence_checker_unittest.cc b/base/sequence_checker_unittest.cc index 7df7614..4fc3027 100644 --- a/base/sequence_checker_unittest.cc +++ b/base/sequence_checker_unittest.cc @@ -1,339 +1,29 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/basictypes.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_loop.h" #include "base/sequence_checker.h" -#include "base/test/sequenced_worker_pool_owner.h" -#include "base/threading/thread.h" -#include "testing/gtest/include/gtest/gtest.h" -// Duplicated from base/sequence_checker.h so that we can be good citizens -// there and undef the macro. -#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) -#define ENABLE_SEQUENCE_CHECKER 1 -#else -#define ENABLE_SEQUENCE_CHECKER 0 -#endif +#include <cstddef> + +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/test/null_task_runner.h" +#include "testing/gtest/include/gtest/gtest.h" namespace base { namespace { -const size_t kNumWorkerThreads = 3; - -// Simple class to exercise the basics of SequenceChecker. -// DoStuff should verify that it's called on a valid sequenced thread. -// SequenceCheckedObject can be destroyed on any thread (like WeakPtr). -class SequenceCheckedObject { - public: - SequenceCheckedObject() {} - ~SequenceCheckedObject() {} - - // Verifies that it was called on the same thread as the constructor. - void DoStuff() { - DCHECK(sequence_checker_.CalledOnValidSequencedThread()); - } - - void DetachFromSequence() { - sequence_checker_.DetachFromSequence(); - } - - private: - SequenceChecker sequence_checker_; - - DISALLOW_COPY_AND_ASSIGN(SequenceCheckedObject); -}; - -class SequenceCheckerTest : public testing::Test { - public: - SequenceCheckerTest() : other_thread_("sequence_checker_test_other_thread") {} - - virtual ~SequenceCheckerTest() {} - - virtual void SetUp() OVERRIDE { - other_thread_.Start(); - ResetPool(); - } - - virtual void TearDown() OVERRIDE { - other_thread_.Stop(); - pool()->Shutdown(); - } - - protected: - base::Thread* other_thread() { return &other_thread_; } - - const scoped_refptr<SequencedWorkerPool>& pool() { - return pool_owner_->pool(); - } - - void PostDoStuffToWorkerPool(SequenceCheckedObject* sequence_checked_object, - const std::string& token_name) { - pool()->PostNamedSequencedWorkerTask( - token_name, - FROM_HERE, - base::Bind(&SequenceCheckedObject::DoStuff, - base::Unretained(sequence_checked_object))); - } - - void PostDoStuffToOtherThread( - SequenceCheckedObject* sequence_checked_object) { - other_thread()->message_loop()->PostTask( - FROM_HERE, - base::Bind(&SequenceCheckedObject::DoStuff, - base::Unretained(sequence_checked_object))); - } - - void PostDeleteToOtherThread( - scoped_ptr<SequenceCheckedObject> sequence_checked_object) { - other_thread()->message_loop()->DeleteSoon( - FROM_HERE, - sequence_checked_object.release()); - } - - // Destroys the SequencedWorkerPool instance, blocking until it is fully shut - // down, and creates a new instance. - void ResetPool() { - pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); - } - - void MethodOnDifferentThreadDeathTest(); - void DetachThenCallFromDifferentThreadDeathTest(); - void DifferentSequenceTokensDeathTest(); - void WorkerPoolAndSimpleThreadDeathTest(); - void TwoDifferentWorkerPoolsDeathTest(); - - private: - MessageLoop message_loop_; // Needed by SequencedWorkerPool to function. - base::Thread other_thread_; - scoped_ptr<SequencedWorkerPoolOwner> pool_owner_; -}; - -TEST_F(SequenceCheckerTest, CallsAllowedOnSameThread) { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - // Verify that DoStuff doesn't assert. - sequence_checked_object->DoStuff(); - - // Verify that the destructor doesn't assert. - sequence_checked_object.reset(); -} - -TEST_F(SequenceCheckerTest, DestructorAllowedOnDifferentThread) { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - // Verify the destructor doesn't assert when called on a different thread. - PostDeleteToOtherThread(sequence_checked_object.Pass()); - other_thread()->Stop(); -} - -TEST_F(SequenceCheckerTest, DetachFromSequence) { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - // Verify that DoStuff doesn't assert when called on a different thread after - // a call to DetachFromSequence. - sequence_checked_object->DetachFromSequence(); - - PostDoStuffToOtherThread(sequence_checked_object.get()); - other_thread()->Stop(); -} - -TEST_F(SequenceCheckerTest, SameSequenceTokenValid) { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - sequence_checked_object->DetachFromSequence(); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - pool()->FlushForTesting(); - - PostDeleteToOtherThread(sequence_checked_object.Pass()); - other_thread()->Stop(); -} - -TEST_F(SequenceCheckerTest, DetachSequenceTokenValid) { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - sequence_checked_object->DetachFromSequence(); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - pool()->FlushForTesting(); - - sequence_checked_object->DetachFromSequence(); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); - pool()->FlushForTesting(); - - PostDeleteToOtherThread(sequence_checked_object.Pass()); - other_thread()->Stop(); -} - -#if GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER - -void SequenceCheckerTest::MethodOnDifferentThreadDeathTest() { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - // DoStuff should assert in debug builds only when called on a - // different thread. - PostDoStuffToOtherThread(sequence_checked_object.get()); - other_thread()->Stop(); -} - -#if ENABLE_SEQUENCE_CHECKER -TEST_F(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadDeathTestInDebug) { - // The default style "fast" does not support multi-threaded tests. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - ASSERT_DEATH({ - MethodOnDifferentThreadDeathTest(); - }, ""); -} -#else -TEST_F(SequenceCheckerTest, MethodAllowedOnDifferentThreadDeathTestInRelease) { - MethodOnDifferentThreadDeathTest(); -} -#endif // ENABLE_SEQUENCE_CHECKER - -void SequenceCheckerTest::DetachThenCallFromDifferentThreadDeathTest() { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - // DoStuff doesn't assert when called on a different thread - // after a call to DetachFromSequence. - sequence_checked_object->DetachFromSequence(); - PostDoStuffToOtherThread(sequence_checked_object.get()); - other_thread()->Stop(); - - // DoStuff should assert in debug builds only after moving to - // another thread. - sequence_checked_object->DoStuff(); -} - -#if ENABLE_SEQUENCE_CHECKER -TEST_F(SequenceCheckerTest, DetachFromSequenceDeathTestInDebug) { - // The default style "fast" does not support multi-threaded tests. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - ASSERT_DEATH({ - DetachThenCallFromDifferentThreadDeathTest(); - }, ""); -} -#else -TEST_F(SequenceCheckerTest, DetachFromThreadDeathTestInRelease) { - DetachThenCallFromDifferentThreadDeathTest(); -} -#endif // ENABLE_SEQUENCE_CHECKER - -void SequenceCheckerTest::DifferentSequenceTokensDeathTest() { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - sequence_checked_object->DetachFromSequence(); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "B"); - pool()->FlushForTesting(); - - PostDeleteToOtherThread(sequence_checked_object.Pass()); - other_thread()->Stop(); +// Call various methods of SequenceChecker to make sure nothing blows +// up in either debug or release mode. +TEST(SequenceCheckerTest, Basic) { + SequenceChecker sequence_checker(new NullTaskRunner()); + sequence_checker.CalledOnValidSequence(); + sequence_checker.ChangeSequence(NULL); + sequence_checker.CalledOnValidSequence(); } -#if ENABLE_SEQUENCE_CHECKER -TEST_F(SequenceCheckerTest, DifferentSequenceTokensDeathTestInDebug) { - // The default style "fast" does not support multi-threaded tests. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - ASSERT_DEATH({ - DifferentSequenceTokensDeathTest(); - }, ""); -} -#else -TEST_F(SequenceCheckerTest, - DifferentSequenceTokensDeathTestInRelease) { - DifferentSequenceTokensDeathTest(); -} -#endif // ENABLE_SEQUENCE_CHECKER - -void SequenceCheckerTest::WorkerPoolAndSimpleThreadDeathTest() { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - sequence_checked_object->DetachFromSequence(); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - pool()->FlushForTesting(); - - PostDoStuffToOtherThread(sequence_checked_object.get()); - other_thread()->Stop(); -} - -#if ENABLE_SEQUENCE_CHECKER -TEST_F(SequenceCheckerTest, WorkerPoolAndSimpleThreadDeathTestInDebug) { - // The default style "fast" does not support multi-threaded tests. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - ASSERT_DEATH({ - WorkerPoolAndSimpleThreadDeathTest(); - }, ""); -} -#else -TEST_F(SequenceCheckerTest, - WorkerPoolAndSimpleThreadDeathTestInRelease) { - WorkerPoolAndSimpleThreadDeathTest(); -} -#endif // ENABLE_SEQUENCE_CHECKER - -void SequenceCheckerTest::TwoDifferentWorkerPoolsDeathTest() { - scoped_ptr<SequenceCheckedObject> sequence_checked_object( - new SequenceCheckedObject); - - sequence_checked_object->DetachFromSequence(); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - PostDoStuffToWorkerPool(sequence_checked_object.get(), "A"); - pool()->FlushForTesting(); - - SequencedWorkerPoolOwner second_pool_owner(kNumWorkerThreads, "test2"); - second_pool_owner.pool()->PostNamedSequencedWorkerTask( - "A", - FROM_HERE, - base::Bind(&SequenceCheckedObject::DoStuff, - base::Unretained(sequence_checked_object.get()))); - second_pool_owner.pool()->FlushForTesting(); - second_pool_owner.pool()->Shutdown(); -} - -#if ENABLE_SEQUENCE_CHECKER -TEST_F(SequenceCheckerTest, TwoDifferentWorkerPoolsDeathTestInDebug) { - // The default style "fast" does not support multi-threaded tests. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - ASSERT_DEATH({ - TwoDifferentWorkerPoolsDeathTest(); - }, ""); -} -#else -TEST_F(SequenceCheckerTest, - TwoDifferentWorkerPoolsDeathTestInRelease) { - TwoDifferentWorkerPoolsDeathTest(); -} -#endif // ENABLE_SEQUENCE_CHECKER - -#endif // GTEST_HAS_DEATH_TEST || !ENABLE_SEQUENCE_CHECKER - } // namespace } // namespace base - -// Just in case we ever get lumped together with other compilation units. -#undef ENABLE_SEQUENCE_CHECKER diff --git a/chrome/browser/storage_monitor/storage_monitor.h b/chrome/browser/storage_monitor/storage_monitor.h index 5c0cd96..9d20d60 100644 --- a/chrome/browser/storage_monitor/storage_monitor.h +++ b/chrome/browser/storage_monitor/storage_monitor.h @@ -14,7 +14,6 @@ #include "base/observer_list_threadsafe.h" #include "base/strings/string16.h" #include "base/synchronization/lock.h" -#include "base/threading/thread_checker.h" #include "chrome/browser/storage_monitor/storage_info.h" class ChromeBrowserMainPartsLinux; diff --git a/content/renderer/media/webmediaplayer_ms.h b/content/renderer/media/webmediaplayer_ms.h index fae271b..106e0bc 100644 --- a/content/renderer/media/webmediaplayer_ms.h +++ b/content/renderer/media/webmediaplayer_ms.h @@ -9,7 +9,6 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" -#include "base/threading/thread_checker.h" #include "cc/layers/video_frame_provider.h" #include "media/filters/skcanvas_video_renderer.h" #include "skia/ext/platform_canvas.h" diff --git a/remoting/host/audio_capturer_win.h b/remoting/host/audio_capturer_win.h index 1a7ddad..c871bca 100644 --- a/remoting/host/audio_capturer_win.h +++ b/remoting/host/audio_capturer_win.h @@ -10,7 +10,6 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" -#include "base/threading/thread_checker.h" #include "base/timer/timer.h" #include "base/win/scoped_co_mem.h" #include "base/win/scoped_comptr.h" diff --git a/tools/valgrind/gtest_exclude/base_unittests.gtest.txt b/tools/valgrind/gtest_exclude/base_unittests.gtest.txt index 35c209d..8270720 100644 --- a/tools/valgrind/gtest_exclude/base_unittests.gtest.txt +++ b/tools/valgrind/gtest_exclude/base_unittests.gtest.txt @@ -24,3 +24,7 @@ ConditionVariableTest.LargeFastTaskTest # Flaky under Valgrind, see http://crbug.com/55517 PlatformFile.TouchGetInfoPlatformFile + +# Death test crashes with NULL deref, probably not intended. +# http://crbug.com/261141 +SequenceCheckerTest.*DeathTest* |