diff options
author | leon.han <leon.han@intel.com> | 2015-07-10 19:01:19 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-11 02:01:52 +0000 |
commit | 2c0f9f1c87c48b03dc4ef3582f724fcfff389a52 (patch) | |
tree | b94b87e0ce8610b78fb572309a8ca679ebbeaf38 | |
parent | 76556ecfe0c0f0a5cf09b6c023993d591f5d1098 (diff) | |
download | chromium_src-2c0f9f1c87c48b03dc4ef3582f724fcfff389a52.zip chromium_src-2c0f9f1c87c48b03dc4ef3582f724fcfff389a52.tar.gz chromium_src-2c0f9f1c87c48b03dc4ef3582f724fcfff389a52.tar.bz2 |
Set listener task runner before connect channel.
Renderer main thread will run ChannelProxy::SetListenerTaskRunner()
to set listener task runner, but the task runner may be accessed on
IPC thread at the same time.
This CL is to fix the race condition.
TBR=nasko@chromium.org
BUG=479684
Review URL: https://codereview.chromium.org/1227303002
Cr-Commit-Position: refs/heads/master@{#338425}
-rw-r--r-- | content/child/child_thread_impl.cc | 11 | ||||
-rw-r--r-- | content/child/child_thread_impl.h | 3 | ||||
-rw-r--r-- | content/renderer/in_process_renderer_thread.cc | 2 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.cc | 30 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.h | 9 | ||||
-rw-r--r-- | content/renderer/render_thread_impl_browsertest.cc | 9 | ||||
-rw-r--r-- | content/renderer/renderer_main.cc | 4 |
7 files changed, 57 insertions, 11 deletions
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index bb3cd6d..88ffed7 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc @@ -297,6 +297,13 @@ ChildThreadImpl::Options::Builder::AddStartupFilter( return *this; } +ChildThreadImpl::Options::Builder& +ChildThreadImpl::Options::Builder::ListenerTaskRunner( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + options_.listener_task_runner = task_runner; + return *this; +} + ChildThreadImpl::Options ChildThreadImpl::Options::Builder::Build() { return options_; } @@ -443,6 +450,10 @@ void ChildThreadImpl::Init(const Options& options) { channel_->AddFilter(startup_filter); } + // Set listener task runner before connect channel to avoid data race. + if (options.listener_task_runner) { + channel_->SetListenerTaskRunner(options.listener_task_runner); + } ConnectChannel(options.use_mojo_channel); int connection_timeout = kConnectionTimeoutS; diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index 171165a..9bc2f73 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h @@ -310,6 +310,7 @@ struct ChildThreadImpl::Options { bool use_mojo_channel; scoped_refptr<base::SequencedTaskRunner> browser_process_io_runner; std::vector<IPC::MessageFilter*> startup_filters; + scoped_refptr<base::SingleThreadTaskRunner> listener_task_runner; private: Options(); @@ -323,6 +324,8 @@ class ChildThreadImpl::Options::Builder { Builder& UseMojoChannel(bool use_mojo_channel); Builder& WithChannelName(const std::string& channel_name); Builder& AddStartupFilter(IPC::MessageFilter* filter); + Builder& ListenerTaskRunner( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); Options Build(); diff --git a/content/renderer/in_process_renderer_thread.cc b/content/renderer/in_process_renderer_thread.cc index f2eecf9..8b4b333 100644 --- a/content/renderer/in_process_renderer_thread.cc +++ b/content/renderer/in_process_renderer_thread.cc @@ -21,7 +21,7 @@ InProcessRendererThread::~InProcessRendererThread() { void InProcessRendererThread::Init() { render_process_.reset(new RenderProcessImpl()); - new RenderThreadImpl(params_); + RenderThreadImpl::Create(params_); } void InProcessRendererThread::CleanUp() { diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 8a155a4..153c5fb 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -557,15 +557,36 @@ void RenderThreadImpl::HistogramCustomizer::SetCommonHost( } } +// static +RenderThreadImpl* RenderThreadImpl::Create( + const InProcessChildThreadParams& params) { + scoped_ptr<scheduler::RendererScheduler> renderer_scheduler = + scheduler::RendererScheduler::Create(); + return new RenderThreadImpl(params, renderer_scheduler.Pass()); +} + +// static +RenderThreadImpl* RenderThreadImpl::Create( + scoped_ptr<base::MessageLoop> main_message_loop) { + scoped_ptr<scheduler::RendererScheduler> renderer_scheduler = + scheduler::RendererScheduler::Create(); + return new RenderThreadImpl(main_message_loop.Pass(), + renderer_scheduler.Pass()); +} + RenderThreadImpl* RenderThreadImpl::current() { return lazy_tls.Pointer()->Get(); } -RenderThreadImpl::RenderThreadImpl(const InProcessChildThreadParams& params) +RenderThreadImpl::RenderThreadImpl( + const InProcessChildThreadParams& params, + scoped_ptr<scheduler::RendererScheduler> scheduler) : ChildThreadImpl(Options::Builder() .InBrowserProcess(params) .UseMojoChannel(ShouldUseMojoChannel()) + .ListenerTaskRunner(scheduler->DefaultTaskRunner()) .Build()), + renderer_scheduler_(scheduler.Pass()), raster_worker_pool_(new RasterWorkerPool()) { Init(); } @@ -573,10 +594,13 @@ RenderThreadImpl::RenderThreadImpl(const InProcessChildThreadParams& params) // When we run plugins in process, we actually run them on the render thread, // which means that we need to make the render thread pump UI events. RenderThreadImpl::RenderThreadImpl( - scoped_ptr<base::MessageLoop> main_message_loop) + scoped_ptr<base::MessageLoop> main_message_loop, + scoped_ptr<scheduler::RendererScheduler> scheduler) : ChildThreadImpl(Options::Builder() .UseMojoChannel(ShouldUseMojoChannel()) + .ListenerTaskRunner(scheduler->DefaultTaskRunner()) .Build()), + renderer_scheduler_(scheduler.Pass()), main_message_loop_(main_message_loop.Pass()), raster_worker_pool_(new RasterWorkerPool()) { Init(); @@ -613,8 +637,6 @@ void RenderThreadImpl::Init() { dom_storage_dispatcher_.reset(new DomStorageDispatcher()); main_thread_indexed_db_dispatcher_.reset(new IndexedDBDispatcher( thread_safe_sender())); - renderer_scheduler_ = scheduler::RendererScheduler::Create(); - channel()->SetListenerTaskRunner(renderer_scheduler_->DefaultTaskRunner()); main_thread_cache_storage_dispatcher_.reset( new CacheStorageDispatcher(thread_safe_sender())); embedded_worker_dispatcher_.reset(new EmbeddedWorkerDispatcher()); diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index a6343d1..fc1d874 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h @@ -135,10 +135,11 @@ class CONTENT_EXPORT RenderThreadImpl public GpuChannelHostFactory, NON_EXPORTED_BASE(public CompositorDependencies) { public: + static RenderThreadImpl* Create(const InProcessChildThreadParams& params); + static RenderThreadImpl* Create( + scoped_ptr<base::MessageLoop> main_message_loop); static RenderThreadImpl* current(); - explicit RenderThreadImpl(const InProcessChildThreadParams& params); - explicit RenderThreadImpl(scoped_ptr<base::MessageLoop> main_message_loop); ~RenderThreadImpl() override; void Shutdown() override; @@ -420,6 +421,10 @@ class CONTENT_EXPORT RenderThreadImpl mojo::ServiceProviderPtr exposed_services); protected: + RenderThreadImpl(const InProcessChildThreadParams& params, + scoped_ptr<scheduler::RendererScheduler> scheduler); + RenderThreadImpl(scoped_ptr<base::MessageLoop> main_message_loop, + scoped_ptr<scheduler::RendererScheduler> scheduler); virtual void SetResourceDispatchTaskQueue( const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue); diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc index 6a06f9e..b722b29 100644 --- a/content/renderer/render_thread_impl_browsertest.cc +++ b/content/renderer/render_thread_impl_browsertest.cc @@ -10,6 +10,7 @@ #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" #include "base/thread_task_runner_handle.h" +#include "components/scheduler/renderer/renderer_scheduler.h" #include "content/common/in_process_child_thread_params.h" #include "content/common/resource_messages.h" #include "content/common/websocket_messages.h" @@ -91,8 +92,10 @@ class TestTaskCounter : public base::SingleThreadTaskRunner { class RenderThreadImplForTest : public RenderThreadImpl { public: RenderThreadImplForTest(const InProcessChildThreadParams& params, + scoped_ptr<scheduler::RendererScheduler> scheduler, scoped_refptr<TestTaskCounter> test_task_counter) - : RenderThreadImpl(params), test_task_counter_(test_task_counter) {} + : RenderThreadImpl(params, scheduler.Pass()), + test_task_counter_(test_task_counter) {} ~RenderThreadImplForTest() override {} @@ -163,10 +166,12 @@ class RenderThreadImplBrowserTest : public testing::Test { cmd->AppendSwitchASCII(switches::kContentImageTextureTarget, base::UintToString(GL_TEXTURE_2D)); + scoped_ptr<scheduler::RendererScheduler> renderer_scheduler = + scheduler::RendererScheduler::Create(); thread_ = new RenderThreadImplForTest( InProcessChildThreadParams(test_helper_->GetChannelId(), test_helper_->GetIOTaskRunner()), - test_task_counter_); + renderer_scheduler.Pass(), test_task_counter_); cmd->InitFromArgv(old_argv); thread_->EnsureWebKitInitialized(); diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc index a76df80..12ca560 100644 --- a/content/renderer/renderer_main.cc +++ b/content/renderer/renderer_main.cc @@ -191,7 +191,7 @@ int RendererMain(const MainFunctionParams& parameters) { // TODO(markus): Check if it is OK to unconditionally move this // instruction down. RenderProcessImpl render_process; - new RenderThreadImpl(main_message_loop.Pass()); + RenderThreadImpl::Create(main_message_loop.Pass()); #endif bool run_loop = true; if (!no_sandbox) { @@ -207,7 +207,7 @@ int RendererMain(const MainFunctionParams& parameters) { } #if defined(OS_POSIX) && !defined(OS_MACOSX) RenderProcessImpl render_process; - new RenderThreadImpl(main_message_loop.Pass()); + RenderThreadImpl::Create(main_message_loop.Pass()); #endif base::HighResolutionTimerManager hi_res_timer_manager; |