summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-11 19:35:01 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-11 19:35:01 +0000
commite980798428a26a167a21e4946659d3ec91ebaa7e (patch)
tree339894f0c45fdb2f249347edd433cad1a4e5c9f0 /chrome
parente0d356a578d9dca45568a31ae0ca8471f2f6e8f4 (diff)
downloadchromium_src-e980798428a26a167a21e4946659d3ec91ebaa7e.zip
chromium_src-e980798428a26a167a21e4946659d3ec91ebaa7e.tar.gz
chromium_src-e980798428a26a167a21e4946659d3ec91ebaa7e.tar.bz2
Fixed destruction race bug in FakeNetworkChangeNotifierThread.
Added unit tests for the above bug. BUG=none TEST=unit tests Review URL: http://codereview.chromium.org/2036010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46953 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/common/net/fake_network_change_notifier_thread.cc4
-rw-r--r--chrome/common/net/fake_network_change_notifier_thread.h5
-rw-r--r--chrome/common/net/fake_network_change_notifier_thread_unittest.cc61
3 files changed, 60 insertions, 10 deletions
diff --git a/chrome/common/net/fake_network_change_notifier_thread.cc b/chrome/common/net/fake_network_change_notifier_thread.cc
index 63930ac..6c22d48 100644
--- a/chrome/common/net/fake_network_change_notifier_thread.cc
+++ b/chrome/common/net/fake_network_change_notifier_thread.cc
@@ -30,9 +30,9 @@ FakeNetworkChangeNotifierThread::~FakeNetworkChangeNotifierThread() {
}
void FakeNetworkChangeNotifierThread::Start() {
+ network_change_notifier_.reset(new net::MockNetworkChangeNotifier());
CHECK(thread_.Start());
thread_blocker_.reset(new ThreadBlocker(&thread_));
- network_change_notifier_.reset(new net::MockNetworkChangeNotifier());
thread_blocker_->Block();
}
@@ -43,9 +43,9 @@ void FakeNetworkChangeNotifierThread::Pump() {
void FakeNetworkChangeNotifierThread::Stop() {
thread_blocker_->Unblock();
- network_change_notifier_.reset();
thread_blocker_.reset();
thread_.Stop();
+ network_change_notifier_.reset();
}
void FakeNetworkChangeNotifierThread::NotifyIPAddressChange() {
diff --git a/chrome/common/net/fake_network_change_notifier_thread.h b/chrome/common/net/fake_network_change_notifier_thread.h
index 5a594f1..907a5b1 100644
--- a/chrome/common/net/fake_network_change_notifier_thread.h
+++ b/chrome/common/net/fake_network_change_notifier_thread.h
@@ -50,11 +50,14 @@ class FakeNetworkChangeNotifierThread : public NetworkChangeNotifierThread {
virtual net::NetworkChangeNotifier* GetNetworkChangeNotifier() const;
private:
+ // Used in unit tests.
+ friend class FakeNetworkChangeNotifierThreadDestructionObserver;
+
void NotifyIPAddressChangeOnSourceThread();
+ scoped_ptr<net::MockNetworkChangeNotifier> network_change_notifier_;
base::Thread thread_;
scoped_ptr<ThreadBlocker> thread_blocker_;
- scoped_ptr<net::MockNetworkChangeNotifier> network_change_notifier_;
DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifierThread);
};
diff --git a/chrome/common/net/fake_network_change_notifier_thread_unittest.cc b/chrome/common/net/fake_network_change_notifier_thread_unittest.cc
index 0cfb741..3902888 100644
--- a/chrome/common/net/fake_network_change_notifier_thread_unittest.cc
+++ b/chrome/common/net/fake_network_change_notifier_thread_unittest.cc
@@ -57,13 +57,52 @@ class FlagToggler : public net::NetworkChangeNotifier::Observer {
DISALLOW_COPY_AND_ASSIGN(FlagToggler);
};
+// Utility class that sanity-checks a
+// FakeNetworkChangeNotifierThread's member variables right before its
+// message loop gets destroyed (used in DestructionRace test).
+class FakeNetworkChangeNotifierThreadDestructionObserver
+ : public MessageLoop::DestructionObserver {
+ public:
+ explicit FakeNetworkChangeNotifierThreadDestructionObserver(
+ const FakeNetworkChangeNotifierThread& thread)
+ : thread_(thread) {}
+
+ virtual ~FakeNetworkChangeNotifierThreadDestructionObserver() {}
+
+ virtual void WillDestroyCurrentMessageLoop() {
+ EXPECT_FALSE(thread_.thread_blocker_.get());
+ // We can't use
+ // FakeNetworkChangeNotifierThread::GetNetworkChangeNotifier() as
+ // it would CHECK-fail on the current thread's message loop being
+ // NULL.
+ EXPECT_TRUE(thread_.network_change_notifier_.get());
+ delete this;
+ }
+
+ private:
+ const FakeNetworkChangeNotifierThread& thread_;
+
+ DISALLOW_COPY_AND_ASSIGN(
+ FakeNetworkChangeNotifierThreadDestructionObserver);
+};
+
+// Utility function to add the
+// FakeNetworkChangeNotifierThreadDestructionObserver from the
+// FakeNetworkChangeNotifierThread's thread.
+void AddFakeNetworkChangeNotifierThreadDestructionObserver(
+ const FakeNetworkChangeNotifierThread* thread) {
+ CHECK_EQ(MessageLoop::current(), thread->GetMessageLoop());
+ thread->GetMessageLoop()->AddDestructionObserver(
+ new FakeNetworkChangeNotifierThreadDestructionObserver(*thread));
+}
+
namespace {
-class FakeNetworkChangeNotifierTest : public testing::Test {
+class FakeNetworkChangeNotifierThreadTest : public testing::Test {
protected:
- FakeNetworkChangeNotifierTest() {}
+ FakeNetworkChangeNotifierThreadTest() {}
- virtual ~FakeNetworkChangeNotifierTest() {}
+ virtual ~FakeNetworkChangeNotifierThreadTest() {}
virtual void SetUp() {
thread_.Start();
@@ -77,10 +116,10 @@ class FakeNetworkChangeNotifierTest : public testing::Test {
FlagToggler flag_toggler_;
private:
- DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifierTest);
+ DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifierThreadTest);
};
-TEST_F(FakeNetworkChangeNotifierTest, Pump) {
+TEST_F(FakeNetworkChangeNotifierThreadTest, Pump) {
thread_.GetMessageLoop()->PostTask(
FROM_HERE, NewRunnableMethod(&flag_toggler_, &FlagToggler::ToggleFlag));
EXPECT_FALSE(flag_toggler_.flag());
@@ -88,7 +127,7 @@ TEST_F(FakeNetworkChangeNotifierTest, Pump) {
EXPECT_TRUE(flag_toggler_.flag());
}
-TEST_F(FakeNetworkChangeNotifierTest, Basic) {
+TEST_F(FakeNetworkChangeNotifierThreadTest, Basic) {
thread_.GetMessageLoop()->PostTask(
FROM_HERE,
NewRunnableMethod(&flag_toggler_, &FlagToggler::Observe, &thread_));
@@ -101,7 +140,7 @@ TEST_F(FakeNetworkChangeNotifierTest, Basic) {
EXPECT_TRUE(flag_toggler_.flag());
}
-TEST_F(FakeNetworkChangeNotifierTest, Multiple) {
+TEST_F(FakeNetworkChangeNotifierThreadTest, Multiple) {
FlagToggler observer;
thread_.GetMessageLoop()->PostTask(
FROM_HERE,
@@ -116,6 +155,14 @@ TEST_F(FakeNetworkChangeNotifierTest, Multiple) {
EXPECT_FALSE(flag_toggler_.flag());
}
+TEST_F(FakeNetworkChangeNotifierThreadTest, DestructionRace) {
+ thread_.GetMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableFunction(
+ &AddFakeNetworkChangeNotifierThreadDestructionObserver,
+ &thread_));
+}
+
} // namespace
} // namespace chrome_common_net