Commit bac34b43 authored by Tobias Sargeant's avatar Tobias Sargeant Committed by Commit Bot

[aw] Fix a race associated with terminating a WebView renderer.

Race condition is caused by RenderProcessHost::Shutdown recreating the
sync IPC channel and asynchronously causing SyncContext::OnChannelOpened
to be called on the IO thread.

In the interim the RPH has been deleted, causing the WaitableEvent that
was passed to the SyncContext to be destroyed before it is used.

Because we never intend to use the WaitableEvent to signal shutdown in
WebView, it's simplest to just pass null for the shutdown_event,
indicating that the caller never intends to signal shutdown.

Bug: 904043,865062
Change-Id: I69a51adc78a0f1c0d6f84fbb7206fc9d58e69ed2
Reviewed-on: https://chromium-review.googlesource.com/c/1329670
Commit-Queue: Tobias Sargeant <tobiasjs@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarBo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607343}
parent 5918bde3
...@@ -1587,10 +1587,6 @@ RenderProcessHostImpl::RenderProcessHostImpl( ...@@ -1587,10 +1587,6 @@ RenderProcessHostImpl::RenderProcessHostImpl(
id_)), id_)),
channel_connected_(false), channel_connected_(false),
sent_render_process_ready_(false), sent_render_process_ready_(false),
#if defined(OS_ANDROID)
never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
#endif
renderer_host_binding_(this), renderer_host_binding_(this),
instance_weak_factory_( instance_weak_factory_(
new base::WeakPtrFactory<RenderProcessHostImpl>(this)), new base::WeakPtrFactory<RenderProcessHostImpl>(this)),
...@@ -1902,9 +1898,11 @@ void RenderProcessHostImpl::InitializeChannelProxy() { ...@@ -1902,9 +1898,11 @@ void RenderProcessHostImpl::InitializeChannelProxy() {
// See crbug.com/526842 for details. // See crbug.com/526842 for details.
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
if (GetContentClient()->UsingSynchronousCompositing()) { if (GetContentClient()->UsingSynchronousCompositing()) {
channel_ = IPC::SyncChannel::Create(this, io_task_runner.get(), // Android never performs a clean shutdown, so we pass nullptr for
base::ThreadTaskRunnerHandle::Get(), // shudown_event to indicate that we never intend to signal a shutdown.
&never_signaled_); channel_ =
IPC::SyncChannel::Create(this, io_task_runner.get(),
base::ThreadTaskRunnerHandle::Get(), nullptr);
} }
#endif // OS_ANDROID #endif // OS_ANDROID
if (!channel_) { if (!channel_) {
......
...@@ -834,15 +834,6 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -834,15 +834,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
bool channel_connected_; bool channel_connected_;
bool sent_render_process_ready_; bool sent_render_process_ready_;
#if defined(OS_ANDROID)
// UI thread is the source of sync IPCs and all shutdown signals.
// Therefore a proper shutdown event to unblock the UI thread is not
// possible without massive refactoring shutdown code.
// Luckily Android never performs a clean shutdown. So explicitly
// ignore this problem.
base::WaitableEvent never_signaled_;
#endif
scoped_refptr<ResourceMessageFilter> resource_message_filter_; scoped_refptr<ResourceMessageFilter> resource_message_filter_;
std::unique_ptr<FileSystemManagerImpl, BrowserThread::DeleteOnIOThread> std::unique_ptr<FileSystemManagerImpl, BrowserThread::DeleteOnIOThread>
file_system_manager_impl_; file_system_manager_impl_;
......
...@@ -495,11 +495,13 @@ void SyncChannel::SyncContext::OnChannelError() { ...@@ -495,11 +495,13 @@ void SyncChannel::SyncContext::OnChannelError() {
} }
void SyncChannel::SyncContext::OnChannelOpened() { void SyncChannel::SyncContext::OnChannelOpened() {
shutdown_watcher_.StartWatching( if (shutdown_event_) {
shutdown_event_, shutdown_watcher_.StartWatching(
base::Bind(&SyncChannel::SyncContext::OnShutdownEventSignaled, shutdown_event_,
base::Unretained(this)), base::BindOnce(&SyncChannel::SyncContext::OnShutdownEventSignaled,
base::SequencedTaskRunnerHandle::Get()); base::Unretained(this)),
base::SequencedTaskRunnerHandle::Get());
}
Context::OnChannelOpened(); Context::OnChannelOpened();
} }
...@@ -539,6 +541,11 @@ std::unique_ptr<SyncChannel> SyncChannel::Create( ...@@ -539,6 +541,11 @@ std::unique_ptr<SyncChannel> SyncChannel::Create(
const scoped_refptr<base::SingleThreadTaskRunner>& listener_task_runner, const scoped_refptr<base::SingleThreadTaskRunner>& listener_task_runner,
bool create_pipe_now, bool create_pipe_now,
base::WaitableEvent* shutdown_event) { base::WaitableEvent* shutdown_event) {
// TODO(tobiasjs): The shutdown_event object is passed to a refcounted
// Context object, and as a result it is not easy to ensure that it
// outlives the Context. There should be some way to either reset
// the shutdown_event when it is destroyed, or allow the Context to
// control the lifetime of shutdown_event.
std::unique_ptr<SyncChannel> channel = std::unique_ptr<SyncChannel> channel =
Create(listener, ipc_task_runner, listener_task_runner, shutdown_event); Create(listener, ipc_task_runner, listener_task_runner, shutdown_event);
channel->Init(channel_handle, mode, create_pipe_now); channel->Init(channel_handle, mode, create_pipe_now);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment