| Index: content/browser/browser_thread_unittest.cc
|
| diff --git a/content/browser/browser_thread_unittest.cc b/content/browser/browser_thread_unittest.cc
|
| index f3f37952ff73ea072dfd12e08bb9b0ff08bbaa18..0538819fa3d3bcecfb49604f1f679a9a83b99c70 100644
|
| --- a/content/browser/browser_thread_unittest.cc
|
| +++ b/content/browser/browser_thread_unittest.cc
|
| @@ -7,9 +7,11 @@
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| #include "base/location.h"
|
| +#include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "base/sequenced_task_runner_helpers.h"
|
| #include "base/single_thread_task_runner.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| #include "content/browser/browser_thread_impl.h"
|
| #include "content/public/test/test_browser_thread.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -25,6 +27,10 @@ class BrowserThreadTest : public testing::Test {
|
| base::MessageLoop::QuitWhenIdleClosure());
|
| }
|
|
|
| + void StopFileThread() {
|
| + file_thread_->Stop();
|
| + }
|
| +
|
| protected:
|
| void SetUp() override {
|
| ui_thread_.reset(new BrowserThreadImpl(BrowserThread::UI));
|
| @@ -35,7 +41,7 @@ class BrowserThreadTest : public testing::Test {
|
|
|
| void TearDown() override {
|
| ui_thread_->Stop();
|
| - file_thread_->Stop();
|
| + StopFileThread();
|
| }
|
|
|
| static void BasicFunction(base::MessageLoop* message_loop) {
|
| @@ -72,6 +78,44 @@ class BrowserThreadTest : public testing::Test {
|
| mutable base::MessageLoop loop_;
|
| };
|
|
|
| +class FileThreadDestructionObserver
|
| + : public base::MessageLoop::DestructionObserver {
|
| + public:
|
| + explicit FileThreadDestructionObserver(bool* did_shutdown,
|
| + const base::Closure& callback)
|
| + : callback_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
| + callback_(callback),
|
| + file_task_runner_(
|
| + BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)),
|
| + did_shutdown_(did_shutdown) {
|
| + BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)->PostTask(
|
| + FROM_HERE, base::Bind(&Watch, this));
|
| + }
|
| +
|
| + private:
|
| + static void Watch(FileThreadDestructionObserver* observer) {
|
| + base::MessageLoop::current()->AddDestructionObserver(observer);
|
| + }
|
| +
|
| + // base::MessageLoop::DestructionObserver:
|
| + void WillDestroyCurrentMessageLoop() override {
|
| + // Ensure that even during MessageLoop teardown the BrowserThread ID is
|
| + // correctly associated with this thread and the BrowserThreadTaskRunner
|
| + // knows it's on the right thread.
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| + EXPECT_TRUE(file_task_runner_->BelongsToCurrentThread());
|
| +
|
| + base::MessageLoop::current()->RemoveDestructionObserver(this);
|
| + *did_shutdown_ = true;
|
| + callback_task_runner_->PostTask(FROM_HERE, callback_);
|
| + }
|
| +
|
| + const scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_;
|
| + const base::Closure callback_;
|
| + const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
|
| + bool* did_shutdown_;
|
| +};
|
| +
|
| TEST_F(BrowserThreadTest, PostTask) {
|
| BrowserThread::PostTask(
|
| BrowserThread::FILE,
|
| @@ -118,4 +162,16 @@ TEST_F(BrowserThreadTest, PostTaskAndReply) {
|
| base::RunLoop().Run();
|
| }
|
|
|
| +TEST_F(BrowserThreadTest, RunsTasksOnCurrentThreadDuringShutdown) {
|
| + bool did_shutdown = false;
|
| + base::RunLoop loop;
|
| + FileThreadDestructionObserver observer(&did_shutdown, loop.QuitClosure());
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&BrowserThreadTest::StopFileThread, base::Unretained(this)));
|
| + loop.Run();
|
| +
|
| + EXPECT_TRUE(did_shutdown);
|
| +}
|
| +
|
| } // namespace content
|
|
|