Skip to content

Commit 752eeba

Browse files
Rohit RaoCommit Bot
Rohit Rao
authored and
Commit Bot
committed
Refactor WebThreadImpl, WebSubThread, and WebMainLoop.
WebThreadImpl is now merely a scoped object that binds a provided SingleThreadTaskRunner to a WebThread::ID. It no longer subclasses base::Thread. That functionality has been moved to WebSubThread, which is effectively only used for the IO thread now. This is the //web implementation of https://chromium-review.googlesource.com/c/chromium/src/+/980793. See the description of that CL for more details. BUG=826465 Change-Id: I636051b154c4156bc32517d649081131f9bdd14d Reviewed-on: https://chromium-review.googlesource.com/c/1383140 Commit-Queue: Rohit Rao <[email protected]> Reviewed-by: Gabriel Charette <[email protected]> Reviewed-by: Sylvain Defresne <[email protected]> Cr-Commit-Position: refs/heads/master@{#618761}
1 parent ab50c91 commit 752eeba

13 files changed

+314
-320
lines changed

base/threading/thread_restrictions.h

+5
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ namespace vr {
234234
class VrShell;
235235
}
236236

237+
namespace web {
238+
class WebSubThread;
239+
}
240+
237241
namespace webrtc {
238242
class DesktopConfigurationMonitor;
239243
}
@@ -317,6 +321,7 @@ class BASE_EXPORT ScopedAllowBlocking {
317321
friend class mojo::CoreLibraryInitializer;
318322
friend class resource_coordinator::TabManagerDelegate; // crbug.com/778703
319323
friend class ui::MaterialDesignController;
324+
friend class web::WebSubThread;
320325
friend class StackSamplingProfiler;
321326

322327
ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;

ios/components/io_thread/DEPS

+4
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ include_rules = [
77
"+components/version_info",
88
"+ios/web/public",
99
"+net",
10+
11+
# Temporarily allow WebThreadImpl until TaskExecutor functionality is moved
12+
# into a new file in ios/web/public.
13+
"+ios/web/web_thread_impl.h"
1014
]

ios/components/io_thread/ios_io_thread_unittest.mm

+34-23
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44

55
#include "ios/components/io_thread/ios_io_thread.h"
66

7-
#include "base/message_loop/message_loop.h"
8-
#include "base/run_loop.h"
9-
#include "components/prefs/pref_registry_simple.h"
10-
#include "components/prefs/pref_service.h"
11-
#include "components/prefs/pref_service_factory.h"
12-
#include "components/prefs/testing_pref_store.h"
7+
#include <memory>
8+
9+
#include "base/test/scoped_task_environment.h"
10+
#include "components/prefs/testing_pref_service.h"
1311
#include "components/proxy_config/pref_proxy_config_tracker_impl.h"
14-
#include "ios/web/public/test/test_web_thread_bundle.h"
15-
#include "net/test/url_request/url_request_failed_job.h"
16-
#include "net/url_request/url_request_filter.h"
12+
#import "ios/web/public/test/fakes/test_web_client.h"
13+
#include "ios/web/public/test/scoped_testing_web_client.h"
14+
#include "ios/web/public/test/test_web_thread.h"
15+
#include "ios/web/web_thread_impl.h"
16+
#include "net/base/network_delegate.h"
1717
#include "testing/gtest/include/gtest/gtest.h"
1818
#include "testing/gtest_mac.h"
1919
#include "testing/platform_test.h"
@@ -42,32 +42,43 @@
4242

4343
class IOSIOThreadTest : public PlatformTest {
4444
public:
45-
IOSIOThreadTest() : thread_bundle_(web::TestWebThreadBundle::IO_MAINLOOP) {
46-
net::URLRequestFailedJob::AddUrlHandler();
45+
IOSIOThreadTest() : web_client_(std::make_unique<web::TestWebClient>()) {
46+
web::WebThreadImpl::CreateTaskExecutor();
47+
48+
ui_thread_ = std::make_unique<web::TestWebThread>(
49+
web::WebThread::UI, scoped_task_environment_.GetMainThreadTaskRunner());
4750
}
4851

4952
~IOSIOThreadTest() override {
50-
net::URLRequestFilter::GetInstance()->ClearHandlers();
53+
web::WebThreadImpl::ResetTaskExecutorForTesting();
5154
}
5255

53-
private:
54-
web::TestWebThreadBundle thread_bundle_;
56+
protected:
57+
base::test::ScopedTaskEnvironment scoped_task_environment_;
58+
web::ScopedTestingWebClient web_client_;
59+
std::unique_ptr<web::TestWebThread> ui_thread_;
5560
};
5661

5762
// Tests the creation of an IOSIOThread and verifies that it returns a system
5863
// url request context.
5964
TEST_F(IOSIOThreadTest, AssertSystemUrlRequestContext) {
60-
PrefServiceFactory pref_service_factory;
61-
pref_service_factory.set_user_prefs(base::MakeRefCounted<TestingPrefStore>());
65+
std::unique_ptr<TestingPrefServiceSimple> pref_service(
66+
std::make_unique<TestingPrefServiceSimple>());
67+
PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service->registry());
6268

63-
scoped_refptr<PrefRegistrySimple> pref_registry = new PrefRegistrySimple;
64-
PrefProxyConfigTrackerImpl::RegisterPrefs(pref_registry.get());
69+
// Create the IO thread but do not register it yet.
70+
std::unique_ptr<web::TestWebThread> io_thread(
71+
std::make_unique<web::TestWebThread>(web::WebThread::IO));
72+
io_thread->StartIOThreadUnregistered();
6573

66-
std::unique_ptr<PrefService> pref_service(
67-
pref_service_factory.Create(pref_registry.get()));
68-
69-
std::unique_ptr<TestIOThread> test_io_thread(
74+
// Create the TestIOThread before the IO thread is registered.
75+
std::unique_ptr<TestIOThread> ios_io_thread(
7076
new TestIOThread(pref_service.get(), nullptr));
77+
io_thread->RegisterAsWebThread();
78+
79+
ASSERT_TRUE(ios_io_thread->system_url_request_context_getter());
7180

72-
ASSERT_TRUE(test_io_thread->system_url_request_context_getter());
81+
// Explicitly destroy the IO thread so that it is unregistered before the
82+
// TestIOThread is destroyed.
83+
io_thread.reset();
7384
}

ios/web/app/web_main_loop.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class WebMainLoop {
8383
// This must get destroyed after other threads that are created in parts_.
8484
std::unique_ptr<WebThreadImpl> main_thread_;
8585

86-
// Members initialized in |RunMainMessageLoopParts()| ------------------------
86+
// Members initialized in |CreateThreads()| ------------------------
8787
std::unique_ptr<WebSubThread> io_thread_;
8888

8989
// Members initialized in |WebThreadsStarted()| --------------------------

ios/web/app/web_main_loop.mm

+6-2
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@
130130
base::Thread::Options io_message_loop_options;
131131
io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO;
132132
io_thread_ = std::make_unique<WebSubThread>(WebThread::IO);
133-
io_thread_->StartWithOptions(io_message_loop_options);
133+
if (!io_thread_->StartWithOptions(io_message_loop_options))
134+
LOG(FATAL) << "Failed to start WebThread::IO";
135+
io_thread_->RegisterAsWebThread();
134136

135137
// Only start IO thread above as this is the only WebThread besides UI (which
136138
// is the main thread).
@@ -196,8 +198,10 @@
196198
base::PlatformThread::SetName("CrWebMain");
197199

198200
// Register the main thread by instantiating it, but don't call any methods.
201+
DCHECK(base::ThreadTaskRunnerHandle::IsSet());
199202
main_thread_.reset(new WebThreadImpl(
200-
WebThread::UI, ios_global_state::GetMainThreadMessageLoop()));
203+
WebThread::UI,
204+
ios_global_state::GetMainThreadMessageLoop()->task_runner()));
201205
}
202206

203207
int WebMainLoop::WebThreadsStarted() {

ios/web/public/test/test_web_thread.h

+28-8
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,29 @@
1212

1313
namespace base {
1414
class MessageLoop;
15+
class Thread;
1516
}
1617

1718
namespace web {
1819

19-
class TestWebThreadImpl;
20+
class WebSubThread;
21+
class WebThreadImpl;
2022

2123
// DEPRECATED: use TestWebThreadBundle instead.
2224
// A WebThread for unit tests; this lets unit tests outside of web create
2325
// WebThread instances.
2426
class TestWebThread {
2527
public:
28+
// Constructs a TestWebThread with a |real_thread_| and starts it (with a
29+
// MessageLoopForIO if |identifier == WebThread::IO|).
2630
explicit TestWebThread(WebThread::ID identifier);
31+
32+
// Constructs a TestWebThread "running" on |thread_runner| (no
33+
// |real_thread_|).
34+
TestWebThread(WebThread::ID identifier,
35+
scoped_refptr<base::SingleThreadTaskRunner> thread_runner);
36+
37+
// Constructs a TestWebThread based on |message_loop| (no |real_thread_|).
2738
TestWebThread(WebThread::ID identifier, base::MessageLoop* message_loop);
2839

2940
~TestWebThread();
@@ -33,22 +44,31 @@ class TestWebThread {
3344
// WebThread, do no provide the full Thread interface.
3445

3546
// Starts the thread with a generic message loop.
36-
bool Start();
47+
void Start();
3748

3849
// Starts the thread with an IOThread message loop.
39-
bool StartIOThread();
50+
void StartIOThread();
51+
52+
// Together these are the same as StartIOThread(). They can be called in
53+
// phases to test binding WebThread::IO after its underlying thread was
54+
// started.
55+
void StartIOThreadUnregistered();
56+
void RegisterAsWebThread();
4057

4158
// Stops the thread.
4259
void Stop();
4360

44-
// Returns true if the thread is running.
45-
bool IsRunning();
46-
4761
private:
48-
std::unique_ptr<TestWebThreadImpl> impl_;
49-
5062
const WebThread::ID identifier_;
5163

64+
// A real thread which represents |identifier_| when constructor #1 is used
65+
// (null otherwise).
66+
std::unique_ptr<WebSubThread> real_thread_;
67+
68+
// Binds |identifier_| to |message_loop| when constructor #2 is used (null
69+
// otherwise).
70+
std::unique_ptr<WebThreadImpl> fake_thread_;
71+
5272
DISALLOW_COPY_AND_ASSIGN(TestWebThread);
5373
};
5474

ios/web/public/web_thread.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ class WebThread {
9595
// Only one delegate may be registered at a time. Delegates may be
9696
// unregistered by providing a nullptr pointer.
9797
//
98-
// If the caller unregisters a delegate before CleanUp has been
99-
// called, it must perform its own locking to ensure the delegate is
100-
// not deleted while unregistering.
98+
// The delegate can only be registered through this call before
99+
// WebThreadImpl(WebThread::IO) is created and unregistered after
100+
// it was destroyed and its underlying thread shutdown.
101101
static void SetIOThreadDelegate(WebThreadDelegate* delegate);
102102

103103
// Returns an appropriate error message for when DCHECK_CURRENTLY_ON() fails.

ios/web/public/web_thread_delegate.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ namespace web {
1313
// If registered as such, it will schedule to run Init() before the
1414
// message loop begins, and receive a CleanUp() call right after the message
1515
// loop ends (and before the WebThread has done its own clean-up).
16+
17+
// A delegate for //web embedders to perform extra initialization/cleanup on
18+
// WebThread::IO.
1619
class WebThreadDelegate {
1720
public:
1821
virtual ~WebThreadDelegate() {}
1922

20-
// Called prior to starting the message loop
23+
// Called prior to completing initialization of WebThread::IO.
2124
virtual void Init() = 0;
2225

23-
// Called just after the message loop ends.
26+
// Called during teardown of WebThread::IO.
2427
virtual void CleanUp() = 0;
2528
};
2629

ios/web/test/test_web_thread.cc

+33-31
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,36 @@
66

77
#include "base/macros.h"
88
#include "base/message_loop/message_loop.h"
9+
#include "ios/web/web_sub_thread.h"
910
#include "ios/web/web_thread_impl.h"
1011

1112
namespace web {
1213

13-
class TestWebThreadImpl : public WebThreadImpl {
14-
public:
15-
TestWebThreadImpl(WebThread::ID identifier) : WebThreadImpl(identifier) {}
16-
17-
TestWebThreadImpl(WebThread::ID identifier, base::MessageLoop* message_loop)
18-
: WebThreadImpl(identifier, message_loop) {}
19-
20-
~TestWebThreadImpl() override { Stop(); }
21-
22-
private:
23-
DISALLOW_COPY_AND_ASSIGN(TestWebThreadImpl);
24-
};
25-
2614
TestWebThread::TestWebThread(WebThread::ID identifier)
27-
: impl_(new TestWebThreadImpl(identifier)), identifier_(identifier) {}
15+
: identifier_(identifier),
16+
real_thread_(std::make_unique<WebSubThread>(identifier_)) {
17+
real_thread_->AllowBlockingForTesting();
18+
}
19+
20+
TestWebThread::TestWebThread(
21+
WebThread::ID identifier,
22+
scoped_refptr<base::SingleThreadTaskRunner> thread_runner)
23+
: identifier_(identifier),
24+
fake_thread_(new WebThreadImpl(identifier_, thread_runner)) {}
2825

2926
TestWebThread::TestWebThread(WebThread::ID identifier,
3027
base::MessageLoop* message_loop)
31-
: impl_(new TestWebThreadImpl(identifier, message_loop)),
32-
identifier_(identifier) {}
28+
: TestWebThread(identifier, message_loop->task_runner()) {}
3329

3430
TestWebThread::~TestWebThread() {
3531
// The upcoming WebThreadImpl::ResetGlobalsForTesting() call requires that
36-
// |impl_| have triggered the shutdown phase for its WebThread::ID. This
37-
// either happens when the thread is stopped (if real) or destroyed (when fake
38-
// -- i.e. using an externally provided MessageLoop).
39-
impl_.reset();
32+
// |identifier_| completed its shutdown phase.
33+
real_thread_.reset();
34+
fake_thread_.reset();
4035

41-
// Resets WebThreadImpl's globals so that |impl_| is no longer bound to
42-
// |identifier_|. This is fine since the underlying MessageLoop has already
43-
// been flushed and deleted in Stop(). In the case of an externally provided
36+
// Resets WebThreadImpl's globals so that |identifier_| is no longer
37+
// bound. This is fine since the underlying MessageLoop has already been
38+
// flushed and deleted above. In the case of an externally provided
4439
// MessageLoop however, this means that TaskRunners obtained through
4540
// |WebThreadImpl::GetTaskRunnerForThread(identifier_)| will no longer
4641
// recognize their WebThreadImpl for RunsTasksInCurrentSequence(). This
@@ -54,22 +49,29 @@ TestWebThread::~TestWebThread() {
5449
WebThreadImpl::ResetGlobalsForTesting(identifier_);
5550
}
5651

57-
bool TestWebThread::Start() {
58-
return impl_->Start();
52+
void TestWebThread::Start() {
53+
CHECK(real_thread_->Start());
54+
RegisterAsWebThread();
55+
}
56+
57+
void TestWebThread::StartIOThread() {
58+
StartIOThreadUnregistered();
59+
RegisterAsWebThread();
5960
}
6061

61-
bool TestWebThread::StartIOThread() {
62+
void TestWebThread::StartIOThreadUnregistered() {
6263
base::Thread::Options options;
6364
options.message_loop_type = base::MessageLoop::TYPE_IO;
64-
return impl_->StartWithOptions(options);
65+
CHECK(real_thread_->StartWithOptions(options));
6566
}
6667

67-
void TestWebThread::Stop() {
68-
impl_->Stop();
68+
void TestWebThread::RegisterAsWebThread() {
69+
real_thread_->RegisterAsWebThread();
6970
}
7071

71-
bool TestWebThread::IsRunning() {
72-
return impl_->IsRunning();
72+
void TestWebThread::Stop() {
73+
if (real_thread_)
74+
real_thread_->Stop();
7375
}
7476

7577
} // namespace web

0 commit comments

Comments
 (0)