diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-29 19:22:51 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-29 19:22:51 +0000 |
commit | db9f091c5b80f687d231b8cb13dde2f7e964700b (patch) | |
tree | 3a2f406186a39dc7cb84fa2786293538be111c02 /base/message_loop_proxy_unittest.cc | |
parent | 8275835e508fb36328dd79c338d31bbf98eadf56 (diff) | |
download | chromium_src-db9f091c5b80f687d231b8cb13dde2f7e964700b.zip chromium_src-db9f091c5b80f687d231b8cb13dde2f7e964700b.tar.gz chromium_src-db9f091c5b80f687d231b8cb13dde2f7e964700b.tar.bz2 |
Create a new base/message_loop directory and move the message_loop_proxy.
Eventually we'll move all the message loop and message pump classes into this
directory. This leaves a forwarding header to avoid having to update all
includes in this patch.
BUG=
Review URL: https://codereview.chromium.org/13333003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191422 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_loop_proxy_unittest.cc')
-rw-r--r-- | base/message_loop_proxy_unittest.cc | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/base/message_loop_proxy_unittest.cc b/base/message_loop_proxy_unittest.cc deleted file mode 100644 index aaabef6..0000000 --- a/base/message_loop_proxy_unittest.cc +++ /dev/null @@ -1,266 +0,0 @@ -// 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/message_loop_proxy.h" - -#include "base/atomic_sequence_num.h" -#include "base/bind.h" -#include "base/debug/leak_annotations.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { - -namespace { - -class MessageLoopProxyTest : public testing::Test { - public: - MessageLoopProxyTest() - : current_loop_(new MessageLoop()), - task_thread_("task_thread"), - thread_sync_(true, false) { - } - - void DeleteCurrentMessageLoop() { - current_loop_.reset(); - } - - protected: - virtual void SetUp() OVERRIDE { - // Use SetUp() instead of the constructor to avoid posting a task to a - // partialy constructed object. - task_thread_.Start(); - - // Allow us to pause the |task_thread_|'s MessageLoop. - task_thread_.message_loop()->PostTask( - FROM_HERE, - Bind(&MessageLoopProxyTest::BlockTaskThreadHelper, Unretained(this))); - } - - virtual void TearDown() OVERRIDE { - // Make sure the |task_thread_| is not blocked, and stop the thread - // fully before destuction because its tasks may still depend on the - // |thread_sync_| event. - thread_sync_.Signal(); - task_thread_.Stop(); - DeleteCurrentMessageLoop(); - } - - // Make LoopRecorder threadsafe so that there is defined behavior even if a - // threading mistake sneaks into the PostTaskAndReplyRelay implementation. - class LoopRecorder : public RefCountedThreadSafe<LoopRecorder> { - public: - LoopRecorder(MessageLoop** run_on, MessageLoop** deleted_on, - int* destruct_order) - : run_on_(run_on), - deleted_on_(deleted_on), - destruct_order_(destruct_order) { - } - - void RecordRun() { - *run_on_ = MessageLoop::current(); - } - - private: - friend class RefCountedThreadSafe<LoopRecorder>; - ~LoopRecorder() { - *deleted_on_ = MessageLoop::current(); - *destruct_order_ = g_order.GetNext(); - } - - MessageLoop** run_on_; - MessageLoop** deleted_on_; - int* destruct_order_; - }; - - static void RecordLoop(scoped_refptr<LoopRecorder> recorder) { - recorder->RecordRun(); - } - - static void RecordLoopAndQuit(scoped_refptr<LoopRecorder> recorder) { - recorder->RecordRun(); - MessageLoop::current()->QuitWhenIdle(); - } - - void UnblockTaskThread() { - thread_sync_.Signal(); - } - - void BlockTaskThreadHelper() { - thread_sync_.Wait(); - } - - static StaticAtomicSequenceNumber g_order; - - scoped_ptr<MessageLoop> current_loop_; - Thread task_thread_; - - private: - base::WaitableEvent thread_sync_; -}; - -StaticAtomicSequenceNumber MessageLoopProxyTest::g_order; - -TEST_F(MessageLoopProxyTest, PostTaskAndReply_Basic) { - MessageLoop* task_run_on = NULL; - MessageLoop* task_deleted_on = NULL; - int task_delete_order = -1; - MessageLoop* reply_run_on = NULL; - MessageLoop* reply_deleted_on = NULL; - int reply_delete_order = -1; - - scoped_refptr<LoopRecorder> task_recoder = - new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); - scoped_refptr<LoopRecorder> reply_recoder = - new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); - - ASSERT_TRUE(task_thread_.message_loop_proxy()->PostTaskAndReply( - FROM_HERE, - Bind(&RecordLoop, task_recoder), - Bind(&RecordLoopAndQuit, reply_recoder))); - - // Die if base::Bind doesn't retain a reference to the recorders. - task_recoder = NULL; - reply_recoder = NULL; - ASSERT_FALSE(task_deleted_on); - ASSERT_FALSE(reply_deleted_on); - - UnblockTaskThread(); - current_loop_->Run(); - - EXPECT_EQ(task_thread_.message_loop(), task_run_on); - EXPECT_EQ(current_loop_.get(), task_deleted_on); - EXPECT_EQ(current_loop_.get(), reply_run_on); - EXPECT_EQ(current_loop_.get(), reply_deleted_on); - EXPECT_LT(task_delete_order, reply_delete_order); -} - -TEST_F(MessageLoopProxyTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) { - MessageLoop* task_run_on = NULL; - MessageLoop* task_deleted_on = NULL; - int task_delete_order = -1; - MessageLoop* reply_run_on = NULL; - MessageLoop* reply_deleted_on = NULL; - int reply_delete_order = -1; - - scoped_refptr<LoopRecorder> task_recoder = - new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); - scoped_refptr<LoopRecorder> reply_recoder = - new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); - - // Grab a MessageLoopProxy to a dead MessageLoop. - scoped_refptr<MessageLoopProxy> task_loop_proxy = - task_thread_.message_loop_proxy(); - UnblockTaskThread(); - task_thread_.Stop(); - - ASSERT_FALSE(task_loop_proxy->PostTaskAndReply( - FROM_HERE, - Bind(&RecordLoop, task_recoder), - Bind(&RecordLoopAndQuit, reply_recoder))); - - // The relay should have properly deleted its resources leaving us as the only - // reference. - EXPECT_EQ(task_delete_order, reply_delete_order); - ASSERT_TRUE(task_recoder->HasOneRef()); - ASSERT_TRUE(reply_recoder->HasOneRef()); - - // Nothing should have run though. - EXPECT_FALSE(task_run_on); - EXPECT_FALSE(reply_run_on); -} - -TEST_F(MessageLoopProxyTest, PostTaskAndReply_SameLoop) { - MessageLoop* task_run_on = NULL; - MessageLoop* task_deleted_on = NULL; - int task_delete_order = -1; - MessageLoop* reply_run_on = NULL; - MessageLoop* reply_deleted_on = NULL; - int reply_delete_order = -1; - - scoped_refptr<LoopRecorder> task_recoder = - new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); - scoped_refptr<LoopRecorder> reply_recoder = - new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); - - // Enqueue the relay. - ASSERT_TRUE(current_loop_->message_loop_proxy()->PostTaskAndReply( - FROM_HERE, - Bind(&RecordLoop, task_recoder), - Bind(&RecordLoopAndQuit, reply_recoder))); - - // Die if base::Bind doesn't retain a reference to the recorders. - task_recoder = NULL; - reply_recoder = NULL; - ASSERT_FALSE(task_deleted_on); - ASSERT_FALSE(reply_deleted_on); - - current_loop_->Run(); - - EXPECT_EQ(current_loop_.get(), task_run_on); - EXPECT_EQ(current_loop_.get(), task_deleted_on); - EXPECT_EQ(current_loop_.get(), reply_run_on); - EXPECT_EQ(current_loop_.get(), reply_deleted_on); - EXPECT_LT(task_delete_order, reply_delete_order); -} - -TEST_F(MessageLoopProxyTest, PostTaskAndReply_DeadReplyLoopDoesNotDelete) { - // Annotate the scope as having memory leaks to suppress heapchecker reports. - ANNOTATE_SCOPED_MEMORY_LEAK; - MessageLoop* task_run_on = NULL; - MessageLoop* task_deleted_on = NULL; - int task_delete_order = -1; - MessageLoop* reply_run_on = NULL; - MessageLoop* reply_deleted_on = NULL; - int reply_delete_order = -1; - - scoped_refptr<LoopRecorder> task_recoder = - new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); - scoped_refptr<LoopRecorder> reply_recoder = - new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); - - // Enqueue the relay. - task_thread_.message_loop_proxy()->PostTaskAndReply( - FROM_HERE, - Bind(&RecordLoop, task_recoder), - Bind(&RecordLoopAndQuit, reply_recoder)); - - // Die if base::Bind doesn't retain a reference to the recorders. - task_recoder = NULL; - reply_recoder = NULL; - ASSERT_FALSE(task_deleted_on); - ASSERT_FALSE(reply_deleted_on); - - UnblockTaskThread(); - - // Mercilessly whack the current loop before |reply| gets to run. - current_loop_.reset(); - - // This should ensure the relay has been run. We need to record the - // MessageLoop pointer before stopping the thread because Thread::Stop() will - // NULL out its own pointer. - MessageLoop* task_loop = task_thread_.message_loop(); - task_thread_.Stop(); - - EXPECT_EQ(task_loop, task_run_on); - ASSERT_FALSE(task_deleted_on); - EXPECT_FALSE(reply_run_on); - ASSERT_FALSE(reply_deleted_on); - EXPECT_EQ(task_delete_order, reply_delete_order); - - // The PostTaskAndReplyRelay is leaked here. Even if we had a reference to - // it, we cannot just delete it because PostTaskAndReplyRelay's destructor - // checks that MessageLoop::current() is the the same as when the - // PostTaskAndReplyRelay object was constructed. However, this loop must have - // aleady been deleted in order to perform this test. See - // http://crbug.com/86301. -} - -} // namespace - -} // namespace base |