| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 #include "base/message_loop_proxy.h" |
| 6 #include "chrome/browser/chrome_thread.h" | 7 #include "chrome/browser/chrome_thread.h" |
| 7 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
| 8 #include "testing/platform_test.h" | 9 #include "testing/platform_test.h" |
| 9 | 10 |
| 10 class ChromeThreadTest : public testing::Test { | 11 class ChromeThreadTest : public testing::Test { |
| 11 public: | 12 public: |
| 12 void Release() { | 13 void Release() { |
| 13 CHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); | 14 CHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 14 loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask); | 15 loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask); |
| 15 } | 16 } |
| 16 | 17 |
| 17 protected: | 18 protected: |
| 18 virtual void SetUp() { | 19 virtual void SetUp() { |
| 20 ui_thread_.reset(new ChromeThread(ChromeThread::UI)); |
| 19 file_thread_.reset(new ChromeThread(ChromeThread::FILE)); | 21 file_thread_.reset(new ChromeThread(ChromeThread::FILE)); |
| 20 io_thread_.reset(new ChromeThread(ChromeThread::IO)); | 22 ui_thread_->Start(); |
| 21 file_thread_->Start(); | 23 file_thread_->Start(); |
| 22 io_thread_->Start(); | |
| 23 } | 24 } |
| 24 | 25 |
| 25 virtual void TearDown() { | 26 virtual void TearDown() { |
| 27 ui_thread_->Stop(); |
| 26 file_thread_->Stop(); | 28 file_thread_->Stop(); |
| 27 io_thread_->Stop(); | |
| 28 } | 29 } |
| 29 | 30 |
| 30 static void BasicFunction(MessageLoop* message_loop) { | 31 static void BasicFunction(MessageLoop* message_loop) { |
| 31 CHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | 32 CHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 32 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask); | 33 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask); |
| 33 } | 34 } |
| 34 | 35 |
| 35 class DummyTask : public Task { | 36 class DummyTask : public Task { |
| 36 public: | 37 public: |
| 37 explicit DummyTask(bool* deleted) : deleted_(deleted) { } | 38 explicit DummyTask(bool* deleted) : deleted_(deleted) { } |
| 38 ~DummyTask() { | 39 ~DummyTask() { |
| 39 *deleted_ = true; | 40 *deleted_ = true; |
| 40 } | 41 } |
| 41 | 42 |
| 42 void Run() { | 43 void Run() { |
| 43 CHECK(false); | 44 CHECK(false); |
| 44 } | 45 } |
| 45 | 46 |
| 46 private: | 47 private: |
| 47 bool* deleted_; | 48 bool* deleted_; |
| 48 }; | 49 }; |
| 49 | 50 |
| 50 class DeletedOnIO | 51 class DeletedOnFile |
| 51 : public base::RefCountedThreadSafe< | 52 : public base::RefCountedThreadSafe< |
| 52 DeletedOnIO, ChromeThread::DeleteOnIOThread> { | 53 DeletedOnFile, ChromeThread::DeleteOnFileThread> { |
| 53 public: | 54 public: |
| 54 explicit DeletedOnIO(MessageLoop* message_loop) | 55 explicit DeletedOnFile(MessageLoop* message_loop) |
| 55 : message_loop_(message_loop) { } | 56 : message_loop_(message_loop) { } |
| 56 | 57 |
| 57 ~DeletedOnIO() { | 58 ~DeletedOnFile() { |
| 58 CHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); | 59 CHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 59 message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 60 message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 60 } | 61 } |
| 61 | 62 |
| 62 private: | 63 private: |
| 63 MessageLoop* message_loop_; | 64 MessageLoop* message_loop_; |
| 64 }; | 65 }; |
| 65 | 66 |
| 66 class NeverDeleted | 67 class NeverDeleted |
| 67 : public base::RefCountedThreadSafe< | 68 : public base::RefCountedThreadSafe< |
| 68 NeverDeleted, ChromeThread::DeleteOnWebKitThread> { | 69 NeverDeleted, ChromeThread::DeleteOnWebKitThread> { |
| 69 public: | 70 public: |
| 70 ~NeverDeleted() { | 71 ~NeverDeleted() { |
| 71 CHECK(false); | 72 CHECK(false); |
| 72 } | 73 } |
| 73 }; | 74 }; |
| 74 | 75 |
| 75 private: | 76 private: |
| 77 scoped_ptr<ChromeThread> ui_thread_; |
| 76 scoped_ptr<ChromeThread> file_thread_; | 78 scoped_ptr<ChromeThread> file_thread_; |
| 77 scoped_ptr<ChromeThread> io_thread_; | |
| 78 MessageLoop loop_; | 79 MessageLoop loop_; |
| 79 }; | 80 }; |
| 80 | 81 |
| 81 TEST_F(ChromeThreadTest, PostTask) { | 82 TEST_F(ChromeThreadTest, PostTask) { |
| 82 ChromeThread::PostTask( | 83 ChromeThread::PostTask( |
| 83 ChromeThread::IO, FROM_HERE, | 84 ChromeThread::FILE, FROM_HERE, |
| 84 NewRunnableFunction(&BasicFunction, MessageLoop::current())); | 85 NewRunnableFunction(&BasicFunction, MessageLoop::current())); |
| 85 MessageLoop::current()->Run(); | 86 MessageLoop::current()->Run(); |
| 86 } | 87 } |
| 87 | 88 |
| 88 TEST_F(ChromeThreadTest, Release) { | 89 TEST_F(ChromeThreadTest, Release) { |
| 89 ChromeThread::ReleaseSoon(ChromeThread::FILE, FROM_HERE, this); | 90 ChromeThread::ReleaseSoon(ChromeThread::UI, FROM_HERE, this); |
| 90 MessageLoop::current()->Run(); | 91 MessageLoop::current()->Run(); |
| 91 } | 92 } |
| 92 | 93 |
| 93 TEST_F(ChromeThreadTest, TaskToNonExistentThreadIsDeleted) { | 94 TEST_F(ChromeThreadTest, TaskToNonExistentThreadIsDeleted) { |
| 94 bool deleted = false; | 95 bool deleted = false; |
| 95 ChromeThread::PostTask( | 96 ChromeThread::PostTask( |
| 96 ChromeThread::WEBKIT, FROM_HERE, | 97 ChromeThread::WEBKIT, FROM_HERE, |
| 97 new DummyTask(&deleted)); | 98 new DummyTask(&deleted)); |
| 98 EXPECT_TRUE(deleted); | 99 EXPECT_TRUE(deleted); |
| 99 } | 100 } |
| 100 | 101 |
| 101 TEST_F(ChromeThreadTest, ReleasedOnCorrectThread) { | 102 TEST_F(ChromeThreadTest, ReleasedOnCorrectThread) { |
| 102 { | 103 { |
| 103 scoped_refptr<DeletedOnIO> test(new DeletedOnIO(MessageLoop::current())); | 104 scoped_refptr<DeletedOnFile> test( |
| 105 new DeletedOnFile(MessageLoop::current())); |
| 104 } | 106 } |
| 105 MessageLoop::current()->Run(); | 107 MessageLoop::current()->Run(); |
| 106 } | 108 } |
| 107 | 109 |
| 108 TEST_F(ChromeThreadTest, NotReleasedIfTargetThreadNonExistent) { | 110 TEST_F(ChromeThreadTest, NotReleasedIfTargetThreadNonExistent) { |
| 109 scoped_refptr<NeverDeleted> test(new NeverDeleted()); | 111 scoped_refptr<NeverDeleted> test(new NeverDeleted()); |
| 110 } | 112 } |
| 113 |
| 114 TEST_F(ChromeThreadTest, PostTaskViaMessageLoopProxy) { |
| 115 scoped_refptr<MessageLoopProxy> message_loop_proxy = |
| 116 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE); |
| 117 message_loop_proxy->PostTask(FROM_HERE, |
| 118 NewRunnableFunction(&BasicFunction, |
| 119 MessageLoop::current())); |
| 120 MessageLoop::current()->Run(); |
| 121 } |
| 122 |
| 123 TEST_F(ChromeThreadTest, ReleaseViaMessageLoopProxy) { |
| 124 scoped_refptr<MessageLoopProxy> message_loop_proxy = |
| 125 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::UI); |
| 126 message_loop_proxy->ReleaseSoon(FROM_HERE, this); |
| 127 MessageLoop::current()->Run(); |
| 128 } |
| 129 |
| 130 TEST_F(ChromeThreadTest, TaskToNonExistentThreadIsDeletedViaMessageLoopProxy) { |
| 131 bool deleted = false; |
| 132 scoped_refptr<MessageLoopProxy> message_loop_proxy = |
| 133 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::WEBKIT); |
| 134 message_loop_proxy->PostTask(FROM_HERE, new DummyTask(&deleted)); |
| 135 EXPECT_TRUE(deleted); |
| 136 } |
| 137 |
| 138 TEST_F(ChromeThreadTest, PostTaskViaMessageLoopProxyAfterThreadExits) { |
| 139 scoped_ptr<ChromeThread> io_thread(new ChromeThread(ChromeThread::IO)); |
| 140 io_thread->Start(); |
| 141 io_thread->Stop(); |
| 142 |
| 143 bool deleted = false; |
| 144 scoped_refptr<MessageLoopProxy> message_loop_proxy = |
| 145 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::IO); |
| 146 bool ret = message_loop_proxy->PostTask(FROM_HERE, new DummyTask(&deleted)); |
| 147 EXPECT_FALSE(ret); |
| 148 EXPECT_TRUE(deleted); |
| 149 } |
| 150 |
| 151 TEST_F(ChromeThreadTest, PostTaskViaMessageLoopProxyAfterThreadIsDeleted) { |
| 152 { |
| 153 scoped_ptr<ChromeThread> io_thread(new ChromeThread(ChromeThread::IO)); |
| 154 io_thread->Start(); |
| 155 } |
| 156 bool deleted = false; |
| 157 scoped_refptr<MessageLoopProxy> message_loop_proxy = |
| 158 ChromeThread::GetMessageLoopProxyForThread(ChromeThread::IO); |
| 159 bool ret = message_loop_proxy->PostTask(FROM_HERE, new DummyTask(&deleted)); |
| 160 EXPECT_FALSE(ret); |
| 161 EXPECT_TRUE(deleted); |
| 162 } |
| 163 |
| OLD | NEW |