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: 15 void Release() const { 16 AssertOnIOThread(); 17 Quit(); 18 } 19 20 void Quit() const { 21 loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask); 22 } 23 24 void AssertOnIOThread() const { 25 ASSERT_TRUE(io_thread_->message_loop_proxy()->BelongsToCurrentThread()); 26 } 27 28 void AssertOnFileThread() const { 29 ASSERT_TRUE(file_thread_->message_loop_proxy()->BelongsToCurrentThread()); 30 } 31 32 protected: 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 40 virtual void TearDown() { 41 io_thread_->Stop(); 42 file_thread_->Stop(); 43 } 44 45 static void BasicFunction(MessageLoopProxyImplTest* test) { 46 test->AssertOnFileThread(); 47 test->Quit(); 48 } 49 50 class DummyTask : public Task { 51 public: 52 explicit DummyTask(bool* deleted) : deleted_(deleted) { } 53 ~DummyTask() { 54 *deleted_ = true; 55 } 56 57 void Run() { 58 FAIL(); 59 } 60 61 private: 62 bool* deleted_; 63 }; 64 65 class DeletedOnFile { 66 public: 67 explicit DeletedOnFile(MessageLoopProxyImplTest* test) : test_(test) {} 68 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 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 92 TEST_F(MessageLoopProxyImplTest, Release) { 93 EXPECT_TRUE(io_thread_->message_loop_proxy()->ReleaseSoon(FROM_HERE, this)); 94 MessageLoop::current()->Run(); 95 } 96 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 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 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