diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-10 03:56:12 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-10 03:56:12 +0000 |
commit | b35254d80932c7a1be75e2a6f271219929a8a3be (patch) | |
tree | f2b7065cb8499e088c73e56aafc091e461139f31 /remoting/base/auto_thread_unittest.cc | |
parent | 42eadc92b2656fe21c3228f4432d28ddac36c6bd (diff) | |
download | chromium_src-b35254d80932c7a1be75e2a6f271219929a8a3be.zip chromium_src-b35254d80932c7a1be75e2a6f271219929a8a3be.tar.gz chromium_src-b35254d80932c7a1be75e2a6f271219929a8a3be.tar.bz2 |
Initial implementation of AutoThread.
AutoThreads work much like base::Threads with the difference that the AutoThread will run until the last reference to its TaskRunner has been dropped. When the owner deletes the AutoThread they will be blocked until the thread is ready to be joined.
AutoThread simplifies teardown of multi-threaded code by ensuring that threads persist until no code remains that may need to use them.
BUG=145856
Review URL: https://chromiumcodereview.appspot.com/10919081
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161030 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base/auto_thread_unittest.cc')
-rw-r--r-- | remoting/base/auto_thread_unittest.cc | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/remoting/base/auto_thread_unittest.cc b/remoting/base/auto_thread_unittest.cc new file mode 100644 index 0000000..65f4aa5 --- /dev/null +++ b/remoting/base/auto_thread_unittest.cc @@ -0,0 +1,115 @@ +// 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/bind.h" +#include "base/memory/ref_counted.h" +#include "remoting/base/auto_thread.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kThreadName[] = "Test thread"; +const char kThreadName2[] = "Test thread 2"; + +void SetFlagTask(bool* success) { + *success = true; +} + +void PostSetFlagTask( + scoped_refptr<base::TaskRunner> task_runner, + bool* success) { + task_runner->PostTask(FROM_HERE, base::Bind(&SetFlagTask, success)); +} + +} // namespace + +namespace remoting { + +class AutoThreadTest : public testing::Test { + public: + AutoThreadTest() : message_loop_quit_correctly_(false) { + } + + void RunMessageLoop() { + // Release |main_task_runner_|, then run |message_loop_| until other + // references created in tests are gone. We also post a delayed quit + // task to |message_loop_| so the test will not hang on failure. + main_task_runner_ = NULL; + message_loop_.PostDelayedTask( + FROM_HERE, MessageLoop::QuitClosure(), base::TimeDelta::FromSeconds(5)); + message_loop_.Run(); + } + + virtual void SetUp() OVERRIDE { + main_task_runner_ = new AutoThreadTaskRunner( + message_loop_.message_loop_proxy(), + base::Bind(&AutoThreadTest::QuitMainMessageLoop, + base::Unretained(this))); + } + + virtual void TearDown() OVERRIDE { + // Verify that |message_loop_| was quit by the AutoThreadTaskRunner. + EXPECT_TRUE(message_loop_quit_correctly_); + } + + protected: + void QuitMainMessageLoop() { + message_loop_quit_correctly_ = true; + message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); + } + + + MessageLoop message_loop_; + bool message_loop_quit_correctly_; + scoped_refptr<AutoThreadTaskRunner> main_task_runner_; +}; + +TEST_F(AutoThreadTest, StartAndStop) { + // Create an AutoThread joined by our MessageLoop. + scoped_refptr<base::TaskRunner> task_runner = + AutoThread::Create(kThreadName, main_task_runner_); + EXPECT_TRUE(task_runner.get()); + + task_runner = NULL; + RunMessageLoop(); +} + +TEST_F(AutoThreadTest, ProcessTask) { + // Create an AutoThread joined by our MessageLoop. + scoped_refptr<base::TaskRunner> task_runner = + AutoThread::Create(kThreadName, main_task_runner_); + EXPECT_TRUE(task_runner.get()); + + // Post a task to it. + bool success = false; + task_runner->PostTask(FROM_HERE, base::Bind(&SetFlagTask, &success)); + + task_runner = NULL; + RunMessageLoop(); + + EXPECT_TRUE(success); +} + +TEST_F(AutoThreadTest, ThreadDependency) { + // Create two AutoThreads joined by our MessageLoop. + scoped_refptr<base::TaskRunner> task_runner1 = + AutoThread::Create(kThreadName, main_task_runner_); + EXPECT_TRUE(task_runner1.get()); + scoped_refptr<base::TaskRunner> task_runner2 = + AutoThread::Create(kThreadName, main_task_runner_); + EXPECT_TRUE(task_runner2.get()); + + // Post a task to thread 1 that will post a task to thread 2. + bool success = false; + task_runner1->PostTask(FROM_HERE, + base::Bind(&PostSetFlagTask, task_runner2, &success)); + + task_runner1 = NULL; + task_runner2 = NULL; + RunMessageLoop(); + + EXPECT_TRUE(success); +} + +} // namespace remoting |