Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 5 | #include "content/public/browser/browser_thread.h" |
| 6 | |
dcheng | 5971627 | 2016-04-09 05:19:08 | [diff] [blame] | 7 | #include <memory> |
| 8 | |
Avi Drissman | adac2199 | 2023-01-11 23:46:39 | [diff] [blame] | 9 | #include "base/functional/bind.h" |
| 10 | #include "base/functional/callback.h" |
| 11 | #include "base/functional/callback_helpers.h" |
skyostil | 95082a6 | 2015-06-05 19:53:07 | [diff] [blame] | 12 | #include "base/location.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 13 | #include "base/memory/raw_ptr.h" |
Alex Clarke | 636e705 | 2019-05-30 10:49:37 | [diff] [blame] | 14 | #include "base/message_loop/message_pump.h" |
Chris Sharp | 7840c58 | 2019-08-02 15:45:32 | [diff] [blame] | 15 | #include "base/message_loop/message_pump_type.h" |
fdoray | e716a90 | 2016-07-05 16:05:49 | [diff] [blame] | 16 | #include "base/run_loop.h" |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 17 | #include "base/task/current_thread.h" |
Gabriel Charette | 067dc8a | 2022-12-01 17:53:29 | [diff] [blame] | 18 | #include "base/task/sequence_manager/sequence_manager.h" |
Sean Maher | e672a66 | 2023-01-09 21:42:28 | [diff] [blame] | 19 | #include "base/task/sequenced_task_runner.h" |
Patrick Monette | 643cdf6 | 2021-10-15 19:13:42 | [diff] [blame] | 20 | #include "base/task/sequenced_task_runner_helpers.h" |
| 21 | #include "base/task/single_thread_task_runner.h" |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 22 | #include "base/test/mock_callback.h" |
Gabriel Charette | c710874 | 2019-08-23 03:31:40 | [diff] [blame] | 23 | #include "base/test/task_environment.h" |
Gabriel Charette | d87f10f | 2022-03-31 00:44:22 | [diff] [blame] | 24 | #include "base/time/time.h" |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 25 | #include "build/build_config.h" |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 26 | #include "content/browser/browser_process_io_thread.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 27 | #include "content/browser/browser_thread_impl.h" |
Gabriel Charette | 748577aa | 2019-08-12 12:53:55 | [diff] [blame] | 28 | #include "content/browser/scheduler/browser_io_thread_delegate.h" |
Alex Clarke | 7dc412d | 2018-09-14 10:02:31 | [diff] [blame] | 29 | #include "content/browser/scheduler/browser_task_executor.h" |
Scott Haseley | 72d89b0 | 2023-02-17 03:29:25 | [diff] [blame] | 30 | #include "content/browser/scheduler/browser_task_priority.h" |
Alex Clarke | 831ed1e6 | 2019-02-18 21:10:08 | [diff] [blame] | 31 | #include "content/browser/scheduler/browser_ui_thread_scheduler.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 32 | #include "testing/gtest/include/gtest/gtest.h" |
[email protected] | 23887f04f | 2008-12-02 19:20:15 | [diff] [blame] | 33 | #include "testing/platform_test.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 34 | |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 35 | namespace content { |
| 36 | |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 37 | namespace { |
| 38 | |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 39 | using ::testing::Invoke; |
| 40 | |
Gabriel Charette | 748577aa | 2019-08-12 12:53:55 | [diff] [blame] | 41 | class SequenceManagerThreadDelegate : public base::Thread::Delegate { |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 42 | public: |
Gabriel Charette | 748577aa | 2019-08-12 12:53:55 | [diff] [blame] | 43 | SequenceManagerThreadDelegate() { |
Scott Haseley | 72d89b0 | 2023-02-17 03:29:25 | [diff] [blame] | 44 | ui_sequence_manager_ = base::sequence_manager::CreateUnboundSequenceManager( |
| 45 | base::sequence_manager::SequenceManager::Settings::Builder() |
| 46 | .SetPrioritySettings(internal::CreateBrowserTaskPrioritySettings()) |
| 47 | .Build()); |
Carlos Caballero | 12a834ad | 2019-04-23 13:48:28 | [diff] [blame] | 48 | auto browser_ui_thread_scheduler = |
Etienne Pierre-doray | 40545ac | 2021-11-11 13:34:28 | [diff] [blame] | 49 | BrowserUIThreadScheduler::CreateForTesting(ui_sequence_manager_.get()); |
Carlos Caballero | 12a834ad | 2019-04-23 13:48:28 | [diff] [blame] | 50 | |
Carlos Caballero | 72e8a20 | 2019-05-21 16:51:17 | [diff] [blame] | 51 | default_task_runner_ = |
Alex Clarke | 49854cc | 2019-06-27 08:25:49 | [diff] [blame] | 52 | browser_ui_thread_scheduler->GetHandle()->GetDefaultTaskRunner(); |
Carlos Caballero | 12a834ad | 2019-04-23 13:48:28 | [diff] [blame] | 53 | |
Alex Clarke | bbf891dc | 2019-10-09 14:18:02 | [diff] [blame] | 54 | ui_sequence_manager_->SetDefaultTaskRunner(default_task_runner_); |
Carlos Caballero | 12a834ad | 2019-04-23 13:48:28 | [diff] [blame] | 55 | |
Carlos Caballero | e840fc3 | 2019-05-27 14:16:37 | [diff] [blame] | 56 | BrowserTaskExecutor::CreateForTesting( |
| 57 | std::move(browser_ui_thread_scheduler), |
Alex Clarke | bbf891dc | 2019-10-09 14:18:02 | [diff] [blame] | 58 | std::make_unique<BrowserIOThreadDelegate>()); |
Minoru Chikamune | a031756 | 2022-03-22 15:30:21 | [diff] [blame] | 59 | BrowserTaskExecutor::OnStartupComplete(); |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 60 | } |
| 61 | |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 62 | SequenceManagerThreadDelegate(const SequenceManagerThreadDelegate&) = delete; |
| 63 | SequenceManagerThreadDelegate& operator=( |
| 64 | const SequenceManagerThreadDelegate&) = delete; |
| 65 | |
Gabriel Charette | 748577aa | 2019-08-12 12:53:55 | [diff] [blame] | 66 | ~SequenceManagerThreadDelegate() override { |
Carlos Caballero | 1209b31 | 2019-04-01 13:30:41 | [diff] [blame] | 67 | BrowserTaskExecutor::ResetForTesting(); |
| 68 | } |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 69 | |
Gabriel Charette | 748577aa | 2019-08-12 12:53:55 | [diff] [blame] | 70 | // Thread::Delegate: |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 71 | scoped_refptr<base::SingleThreadTaskRunner> GetDefaultTaskRunner() override { |
| 72 | return default_task_runner_; |
| 73 | } |
| 74 | |
Etienne Pierre-doray | ef5dcca | 2023-07-11 16:46:27 | [diff] [blame] | 75 | void BindToCurrentThread() override { |
Alex Clarke | bbf891dc | 2019-10-09 14:18:02 | [diff] [blame] | 76 | ui_sequence_manager_->BindToMessagePump( |
Chris Sharp | 7840c58 | 2019-08-02 15:45:32 | [diff] [blame] | 77 | base::MessagePump::Create(base::MessagePumpType::DEFAULT)); |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 78 | } |
| 79 | |
Jiahe Zhang | 93e2eda | 2025-07-16 03:32:34 | [diff] [blame] | 80 | void AddTaskObserver(base::TaskObserver* observer) override { |
| 81 | ui_sequence_manager_->AddTaskObserver(observer); |
| 82 | } |
| 83 | |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 84 | private: |
Alex Clarke | bbf891dc | 2019-10-09 14:18:02 | [diff] [blame] | 85 | std::unique_ptr<base::sequence_manager::SequenceManager> ui_sequence_manager_; |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 86 | scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; |
Alex Clarke | 636d6b6 | 2019-02-22 01:39:04 | [diff] [blame] | 87 | }; |
| 88 | |
| 89 | } // namespace |
| 90 | |
[email protected] | 092b04e | 2010-10-12 23:23:44 | [diff] [blame] | 91 | class BrowserThreadTest : public testing::Test { |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 92 | public: |
[email protected] | 00ed48f | 2010-10-22 22:19:24 | [diff] [blame] | 93 | void Release() const { |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 94 | EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 95 | EXPECT_TRUE(on_release_); |
| 96 | std::move(on_release_).Run(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 97 | } |
[email protected] | 64cd0d12 | 2008-10-17 21:16:13 | [diff] [blame] | 98 | |
CJ DiMeglio | 638cf54 | 2018-12-08 02:22:14 | [diff] [blame] | 99 | void AddRef() {} |
| 100 | |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 101 | protected: |
dcheng | fa85b15 | 2014-10-28 01:13:42 | [diff] [blame] | 102 | void SetUp() override { |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 103 | ui_thread_ = std::make_unique<base::Thread>( |
| 104 | BrowserThreadImpl::GetThreadName(BrowserThread::UI)); |
Alex Clarke | 4779e4bd | 2019-02-15 22:32:03 | [diff] [blame] | 105 | base::Thread::Options ui_options; |
Olivier Li | 89911c4 | 2021-07-02 21:27:02 | [diff] [blame] | 106 | ui_options.delegate = std::make_unique<SequenceManagerThreadDelegate>(); |
| 107 | ui_thread_->StartWithOptions(std::move(ui_options)); |
Gabriel Charette | 8eb4dff | 2018-03-27 14:22:54 | [diff] [blame] | 108 | |
Carlos Caballero | e840fc3 | 2019-05-27 14:16:37 | [diff] [blame] | 109 | io_thread_ = BrowserTaskExecutor::CreateIOThread(); |
Gabriel Charette | 8eb4dff | 2018-03-27 14:22:54 | [diff] [blame] | 110 | io_thread_->RegisterAsBrowserThread(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 111 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 112 | |
dcheng | fa85b15 | 2014-10-28 01:13:42 | [diff] [blame] | 113 | void TearDown() override { |
Gabriel Charette | 8eb4dff | 2018-03-27 14:22:54 | [diff] [blame] | 114 | io_thread_.reset(); |
| 115 | ui_thread_.reset(); |
| 116 | |
Gabriel Charette | e9748f27 | 2017-10-25 19:31:15 | [diff] [blame] | 117 | BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::IO); |
Karolina Soltys | b083f93 | 2019-09-25 16:18:06 | [diff] [blame] | 118 | BrowserTaskExecutor::ResetForTesting(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 119 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 120 | |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 121 | // Prepares this BrowserThreadTest for Release() to be invoked. |on_release| |
| 122 | // will be invoked when this occurs. |
| 123 | void ExpectRelease(base::OnceClosure on_release) { |
| 124 | on_release_ = std::move(on_release); |
| 125 | } |
| 126 | |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 127 | static void BasicFunction(base::OnceClosure continuation, |
| 128 | BrowserThread::ID target) { |
| 129 | EXPECT_TRUE(BrowserThread::CurrentlyOn(target)); |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 130 | std::move(continuation).Run(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 131 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 132 | |
Gabriel Charette | e9748f27 | 2017-10-25 19:31:15 | [diff] [blame] | 133 | class DeletedOnIO |
| 134 | : public base::RefCountedThreadSafe<DeletedOnIO, |
| 135 | BrowserThread::DeleteOnIOThread> { |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 136 | public: |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 137 | explicit DeletedOnIO(base::OnceClosure on_deletion) |
| 138 | : on_deletion_(std::move(on_deletion)) {} |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 139 | |
[email protected] | fb90c94 | 2012-04-27 23:40:50 | [diff] [blame] | 140 | private: |
Gabriel Charette | e9748f27 | 2017-10-25 19:31:15 | [diff] [blame] | 141 | friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>; |
| 142 | friend class base::DeleteHelper<DeletedOnIO>; |
[email protected] | fb90c94 | 2012-04-27 23:40:50 | [diff] [blame] | 143 | |
Gabriel Charette | e9748f27 | 2017-10-25 19:31:15 | [diff] [blame] | 144 | ~DeletedOnIO() { |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 145 | EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 146 | std::move(on_deletion_).Run(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 147 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 148 | |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 149 | base::OnceClosure on_deletion_; |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 150 | }; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 151 | |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 152 | private: |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 153 | std::unique_ptr<base::Thread> ui_thread_; |
| 154 | std::unique_ptr<BrowserProcessIOThread> io_thread_; |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 155 | |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 156 | base::test::TaskEnvironment task_environment_; |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 157 | // Must be set before Release() to verify the deletion is intentional. Will be |
| 158 | // run from the next call to Release(). mutable so it can be consumed from |
| 159 | // Release(). |
| 160 | mutable base::OnceClosure on_release_; |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 161 | }; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 162 | |
fdoray | f854c91 | 2016-10-10 14:51:07 | [diff] [blame] | 163 | class UIThreadDestructionObserver |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 164 | : public base::CurrentThread::DestructionObserver { |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 165 | public: |
fdoray | f854c91 | 2016-10-10 14:51:07 | [diff] [blame] | 166 | explicit UIThreadDestructionObserver(bool* did_shutdown, |
danakj | 151f8fdd | 2019-12-11 03:11:14 | [diff] [blame] | 167 | base::OnceClosure callback) |
Sean Maher | 5b9af51f | 2022-11-21 15:32:47 | [diff] [blame] | 168 | : callback_task_runner_( |
| 169 | base::SingleThreadTaskRunner::GetCurrentDefault()), |
Gabriel Charette | 49e3cd0 | 2020-01-28 03:45:27 | [diff] [blame] | 170 | ui_task_runner_(GetUIThreadTaskRunner({})), |
danakj | 151f8fdd | 2019-12-11 03:11:14 | [diff] [blame] | 171 | callback_(std::move(callback)), |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 172 | did_shutdown_(did_shutdown) { |
Eric Seckler | 4d89f64 | 2018-09-20 18:16:16 | [diff] [blame] | 173 | ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(&Watch, this)); |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | private: |
fdoray | f854c91 | 2016-10-10 14:51:07 | [diff] [blame] | 177 | static void Watch(UIThreadDestructionObserver* observer) { |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 178 | base::CurrentThread::Get()->AddDestructionObserver(observer); |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 179 | } |
| 180 | |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 181 | // base::CurrentThread::DestructionObserver: |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 182 | void WillDestroyCurrentMessageLoop() override { |
| 183 | // Ensure that even during MessageLoop teardown the BrowserThread ID is |
| 184 | // correctly associated with this thread and the BrowserThreadTaskRunner |
| 185 | // knows it's on the right thread. |
fdoray | f854c91 | 2016-10-10 14:51:07 | [diff] [blame] | 186 | EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 187 | EXPECT_TRUE(ui_task_runner_->BelongsToCurrentThread()); |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 188 | |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 189 | base::CurrentThread::Get()->RemoveDestructionObserver(this); |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 190 | *did_shutdown_ = true; |
danakj | 151f8fdd | 2019-12-11 03:11:14 | [diff] [blame] | 191 | callback_task_runner_->PostTask(FROM_HERE, std::move(callback_)); |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 192 | } |
| 193 | |
| 194 | const scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_; |
fdoray | f854c91 | 2016-10-10 14:51:07 | [diff] [blame] | 195 | const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; |
danakj | 151f8fdd | 2019-12-11 03:11:14 | [diff] [blame] | 196 | base::OnceClosure callback_; |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 197 | raw_ptr<bool> did_shutdown_; |
rockot | 48a6aac | 2016-07-28 17:23:54 | [diff] [blame] | 198 | }; |
| 199 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 200 | TEST_F(BrowserThreadTest, PostTask) { |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 201 | base::RunLoop run_loop; |
Michael Thiessen | ab67d39 | 2023-03-16 03:14:53 | [diff] [blame] | 202 | EXPECT_TRUE(GetIOThreadTaskRunner({})->PostTask( |
| 203 | FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), |
| 204 | BrowserThread::IO))); |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 205 | run_loop.Run(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 206 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 207 | |
[email protected] | 092b04e | 2010-10-12 23:23:44 | [diff] [blame] | 208 | TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) { |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 209 | base::RunLoop run_loop; |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 210 | { |
Gabriel Charette | e9748f27 | 2017-10-25 19:31:15 | [diff] [blame] | 211 | scoped_refptr<DeletedOnIO> test( |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 212 | new DeletedOnIO(run_loop.QuitWhenIdleClosure())); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 213 | } |
Gabriel Charette | 69759340 | 2018-04-30 21:23:40 | [diff] [blame] | 214 | run_loop.Run(); |
[email protected] | f671062 | 2009-11-02 06:10:30 | [diff] [blame] | 215 | } |
| 216 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 217 | TEST_F(BrowserThreadTest, PostTaskViaTaskRunner) { |
Gabriel Charette | 49e3cd0 | 2020-01-28 03:45:27 | [diff] [blame] | 218 | scoped_refptr<base::TaskRunner> task_runner = GetIOThreadTaskRunner({}); |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 219 | base::RunLoop run_loop; |
| 220 | EXPECT_TRUE(task_runner->PostTask( |
| 221 | FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), |
| 222 | BrowserThread::IO))); |
| 223 | run_loop.Run(); |
| 224 | } |
| 225 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 226 | TEST_F(BrowserThreadTest, PostTaskViaSequencedTaskRunner) { |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 227 | scoped_refptr<base::SequencedTaskRunner> task_runner = |
Gabriel Charette | 49e3cd0 | 2020-01-28 03:45:27 | [diff] [blame] | 228 | GetIOThreadTaskRunner({}); |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 229 | base::RunLoop run_loop; |
| 230 | EXPECT_TRUE(task_runner->PostTask( |
| 231 | FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), |
| 232 | BrowserThread::IO))); |
| 233 | run_loop.Run(); |
| 234 | } |
| 235 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 236 | TEST_F(BrowserThreadTest, PostTaskViaSingleThreadTaskRunner) { |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 237 | scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
Gabriel Charette | 49e3cd0 | 2020-01-28 03:45:27 | [diff] [blame] | 238 | GetIOThreadTaskRunner({}); |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 239 | base::RunLoop run_loop; |
| 240 | EXPECT_TRUE(task_runner->PostTask( |
| 241 | FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(), |
| 242 | BrowserThread::IO))); |
| 243 | run_loop.Run(); |
| 244 | } |
| 245 | |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 246 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 247 | TEST_F(BrowserThreadTest, ReleaseViaTaskRunner) { |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 248 | scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 249 | GetIOThreadTaskRunner({}); |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 250 | base::RunLoop run_loop; |
| 251 | ExpectRelease(run_loop.QuitWhenIdleClosure()); |
CJ DiMeglio | 638cf54 | 2018-12-08 02:22:14 | [diff] [blame] | 252 | task_runner->ReleaseSoon(FROM_HERE, base::WrapRefCounted(this)); |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 253 | run_loop.Run(); |
| 254 | } |
| 255 | |
Sami Kyostila | 8e4d5a9 | 2019-08-02 12:45:05 | [diff] [blame] | 256 | TEST_F(BrowserThreadTest, PostTaskAndReply) { |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 257 | // Most of the heavy testing for PostTaskAndReply() is done inside the |
| 258 | // task runner test. This just makes sure we get piped through at all. |
| 259 | base::RunLoop run_loop; |
Gabriel Charette | 49e3cd0 | 2020-01-28 03:45:27 | [diff] [blame] | 260 | ASSERT_TRUE(GetIOThreadTaskRunner({})->PostTaskAndReply( |
| 261 | FROM_HERE, base::DoNothing(), run_loop.QuitWhenIdleClosure())); |
Eric Seckler | e329cb9 | 2018-08-28 16:09:40 | [diff] [blame] | 262 | run_loop.Run(); |
| 263 | } |
| 264 | |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 265 | class BrowserThreadWithCustomSchedulerTest : public testing::Test { |
| 266 | private: |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 267 | class TaskEnvironmentWithCustomScheduler |
| 268 | : public base::test::TaskEnvironment { |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 269 | public: |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 270 | TaskEnvironmentWithCustomScheduler() |
Scott Haseley | 72d89b0 | 2023-02-17 03:29:25 | [diff] [blame] | 271 | : base::test::TaskEnvironment( |
| 272 | internal::CreateBrowserTaskPrioritySettings(), |
| 273 | SubclassCreatesDefaultTaskRunner{}) { |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 274 | std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler = |
Etienne Pierre-doray | 40545ac | 2021-11-11 13:34:28 | [diff] [blame] | 275 | BrowserUIThreadScheduler::CreateForTesting(sequence_manager()); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 276 | DeferredInitFromSubclass( |
Alex Clarke | 49854cc | 2019-06-27 08:25:49 | [diff] [blame] | 277 | browser_ui_thread_scheduler->GetHandle()->GetBrowserTaskRunner( |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 278 | QueueType::kDefault)); |
| 279 | BrowserTaskExecutor::CreateForTesting( |
| 280 | std::move(browser_ui_thread_scheduler), |
Alex Clarke | bbf891dc | 2019-10-09 14:18:02 | [diff] [blame] | 281 | std::make_unique<BrowserIOThreadDelegate>()); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 282 | |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 283 | io_thread_ = BrowserTaskExecutor::CreateIOThread(); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 284 | BrowserTaskExecutor::InitializeIOThread(); |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 285 | io_thread_->RegisterAsBrowserThread(); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 286 | } |
| 287 | |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 288 | ~TaskEnvironmentWithCustomScheduler() override { |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 289 | io_thread_.reset(); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 290 | BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::IO); |
| 291 | BrowserTaskExecutor::ResetForTesting(); |
| 292 | } |
| 293 | |
| 294 | private: |
John Abd-El-Malek | f3243dc | 2021-05-07 16:20:01 | [diff] [blame] | 295 | std::unique_ptr<BrowserProcessIOThread> io_thread_; |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 296 | }; |
| 297 | |
| 298 | public: |
| 299 | using QueueType = BrowserTaskQueues::QueueType; |
| 300 | |
| 301 | protected: |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 302 | TaskEnvironmentWithCustomScheduler task_environment_; |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 303 | }; |
| 304 | |
| 305 | TEST_F(BrowserThreadWithCustomSchedulerTest, PostBestEffortTask) { |
danakj | 151f8fdd | 2019-12-11 03:11:14 | [diff] [blame] | 306 | base::MockOnceClosure best_effort_task; |
| 307 | base::MockOnceClosure regular_task; |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 308 | |
Gabriel Charette | e7cdc5cd | 2020-05-27 23:35:05 | [diff] [blame] | 309 | auto task_runner = GetUIThreadTaskRunner({base::TaskPriority::HIGHEST}); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 310 | |
| 311 | task_runner->PostTask(FROM_HERE, regular_task.Get()); |
| 312 | BrowserThread::PostBestEffortTask(FROM_HERE, task_runner, |
| 313 | best_effort_task.Get()); |
| 314 | |
danakj | 151f8fdd | 2019-12-11 03:11:14 | [diff] [blame] | 315 | EXPECT_CALL(regular_task, Run).Times(1); |
| 316 | EXPECT_CALL(best_effort_task, Run).Times(0); |
Gabriel Charette | 694c3c33 | 2019-08-19 14:53:05 | [diff] [blame] | 317 | task_environment_.RunUntilIdle(); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 318 | |
| 319 | testing::Mock::VerifyAndClearExpectations(®ular_task); |
| 320 | |
Minoru Chikamune | a031756 | 2022-03-22 15:30:21 | [diff] [blame] | 321 | BrowserTaskExecutor::OnStartupComplete(); |
Carlos Caballero | 4118f7e | 2019-05-28 13:54:00 | [diff] [blame] | 322 | base::RunLoop run_loop; |
| 323 | EXPECT_CALL(best_effort_task, Run).WillOnce(Invoke([&]() { |
| 324 | run_loop.Quit(); |
| 325 | })); |
| 326 | run_loop.Run(); |
| 327 | } |
| 328 | |
[email protected] | 2b9eb387 | 2013-03-30 18:58:30 | [diff] [blame] | 329 | } // namespace content |