1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/scoped_ptr.h"
6 #include "base/message_loop.h"
7 #include "base/message_loop_proxy_impl.h"
8 #include "base/threading/thread.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "testing/platform_test.h"
11
12
13 class MessageLoopProxyImplTest : public testing::Test {
14 public:
Release() const15 void Release() const {
16 AssertOnIOThread();
17 Quit();
18 }
19
Quit() const20 void Quit() const {
21 loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask);
22 }
23
AssertOnIOThread() const24 void AssertOnIOThread() const {
25 ASSERT_TRUE(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
26 }
27
AssertOnFileThread() const28 void AssertOnFileThread() const {
29 ASSERT_TRUE(file_thread_->message_loop_proxy()->BelongsToCurrentThread());
30 }
31
32 protected:
SetUp()33 virtual void SetUp() {
34 io_thread_.reset(new base::Thread("MessageLoopProxyImplTest_IO"));
35 file_thread_.reset(new base::Thread("MessageLoopProxyImplTest_File"));
36 io_thread_->Start();
37 file_thread_->Start();
38 }
39
TearDown()40 virtual void TearDown() {
41 io_thread_->Stop();
42 file_thread_->Stop();
43 }
44
BasicFunction(MessageLoopProxyImplTest * test)45 static void BasicFunction(MessageLoopProxyImplTest* test) {
46 test->AssertOnFileThread();
47 test->Quit();
48 }
49
50 class DummyTask : public Task {
51 public:
DummyTask(bool * deleted)52 explicit DummyTask(bool* deleted) : deleted_(deleted) { }
~DummyTask()53 ~DummyTask() {
54 *deleted_ = true;
55 }
56
Run()57 void Run() {
58 FAIL();
59 }
60
61 private:
62 bool* deleted_;
63 };
64
65 class DeletedOnFile {
66 public:
DeletedOnFile(MessageLoopProxyImplTest * test)67 explicit DeletedOnFile(MessageLoopProxyImplTest* test) : test_(test) {}
68
~DeletedOnFile()69 ~DeletedOnFile() {
70 test_->AssertOnFileThread();
71 test_->Quit();
72 }
73
74 private:
75 MessageLoopProxyImplTest* test_;
76 };
77
78 scoped_ptr<base::Thread> io_thread_;
79 scoped_ptr<base::Thread> file_thread_;
80
81 private:
82 mutable MessageLoop loop_;
83 };
84
85
TEST_F(MessageLoopProxyImplTest,PostTask)86 TEST_F(MessageLoopProxyImplTest, PostTask) {
87 EXPECT_TRUE(file_thread_->message_loop_proxy()->PostTask(
88 FROM_HERE, NewRunnableFunction(&BasicFunction, this)));
89 MessageLoop::current()->Run();
90 }
91
TEST_F(MessageLoopProxyImplTest,Release)92 TEST_F(MessageLoopProxyImplTest, Release) {
93 EXPECT_TRUE(io_thread_->message_loop_proxy()->ReleaseSoon(FROM_HERE, this));
94 MessageLoop::current()->Run();
95 }
96
TEST_F(MessageLoopProxyImplTest,Delete)97 TEST_F(MessageLoopProxyImplTest, Delete) {
98 DeletedOnFile* deleted_on_file = new DeletedOnFile(this);
99 EXPECT_TRUE(file_thread_->message_loop_proxy()->DeleteSoon(
100 FROM_HERE, deleted_on_file));
101 MessageLoop::current()->Run();
102 }
103
TEST_F(MessageLoopProxyImplTest,PostTaskAfterThreadExits)104 TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadExits) {
105 scoped_ptr<base::Thread> test_thread(
106 new base::Thread("MessageLoopProxyImplTest_Dummy"));
107 test_thread->Start();
108 scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
109 test_thread->message_loop_proxy();
110 test_thread->Stop();
111
112 bool deleted = false;
113 bool ret = message_loop_proxy->PostTask(
114 FROM_HERE, new DummyTask(&deleted));
115 EXPECT_FALSE(ret);
116 EXPECT_TRUE(deleted);
117 }
118
TEST_F(MessageLoopProxyImplTest,PostTaskAfterThreadIsDeleted)119 TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadIsDeleted) {
120 scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
121 {
122 scoped_ptr<base::Thread> test_thread(
123 new base::Thread("MessageLoopProxyImplTest_Dummy"));
124 test_thread->Start();
125 message_loop_proxy = test_thread->message_loop_proxy();
126 }
127 bool deleted = false;
128 bool ret = message_loop_proxy->PostTask(FROM_HERE, new DummyTask(&deleted));
129 EXPECT_FALSE(ret);
130 EXPECT_TRUE(deleted);
131 }
132
133