summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorleon.han <leon.han@intel.com>2015-07-10 19:01:19 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-11 02:01:52 +0000
commit2c0f9f1c87c48b03dc4ef3582f724fcfff389a52 (patch)
treeb94b87e0ce8610b78fb572309a8ca679ebbeaf38
parent76556ecfe0c0f0a5cf09b6c023993d591f5d1098 (diff)
downloadchromium_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.cc11
-rw-r--r--content/child/child_thread_impl.h3
-rw-r--r--content/renderer/in_process_renderer_thread.cc2
-rw-r--r--content/renderer/render_thread_impl.cc30
-rw-r--r--content/renderer/render_thread_impl.h9
-rw-r--r--content/renderer/render_thread_impl_browsertest.cc9
-rw-r--r--content/renderer/renderer_main.cc4
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;