| Index: content/browser/renderer_host/render_process_host_impl.cc
|
| diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
| index efe5da135a9d11d0d430e8232820196a6b520fdd..b81a431e23245da0b4c1125a485799228db7dcb2 100644
|
| --- a/content/browser/renderer_host/render_process_host_impl.cc
|
| +++ b/content/browser/renderer_host/render_process_host_impl.cc
|
| @@ -24,6 +24,7 @@
|
| #include "base/location.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "base/memory/shared_memory.h"
|
| #include "base/memory/shared_memory_handle.h"
|
| #include "base/metrics/histogram.h"
|
| @@ -36,6 +37,7 @@
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/supports_user_data.h"
|
| +#include "base/synchronization/lock.h"
|
| #include "base/sys_info.h"
|
| #include "base/threading/thread.h"
|
| #include "base/threading/thread_restrictions.h"
|
| @@ -463,6 +465,32 @@ static size_t g_max_renderer_count_override = 0;
|
| // static
|
| bool g_run_renderer_in_process_ = false;
|
|
|
| +// Held by the RPH and used to control an (unowned) ConnectionFilterImpl from
|
| +// any thread.
|
| +class RenderProcessHostImpl::ConnectionFilterController
|
| + : public base::RefCountedThreadSafe<ConnectionFilterController> {
|
| + public:
|
| + // |filter| is not owned by this object.
|
| + explicit ConnectionFilterController(ConnectionFilterImpl* filter)
|
| + : filter_(filter) {}
|
| +
|
| + void DisableFilter();
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<ConnectionFilterController>;
|
| + friend class ConnectionFilterImpl;
|
| +
|
| + ~ConnectionFilterController() {}
|
| +
|
| + void Detach() {
|
| + base::AutoLock lock(lock_);
|
| + filter_ = nullptr;
|
| + }
|
| +
|
| + base::Lock lock_;
|
| + ConnectionFilterImpl* filter_;
|
| +};
|
| +
|
| // Held by the RPH's BrowserContext's MojoShellConnection, ownership transferred
|
| // back to RPH upon RPH destruction.
|
| class RenderProcessHostImpl::ConnectionFilterImpl : public ConnectionFilter {
|
| @@ -472,6 +500,7 @@ class RenderProcessHostImpl::ConnectionFilterImpl : public ConnectionFilter {
|
| std::unique_ptr<shell::InterfaceRegistry> registry)
|
| : child_identity_(child_identity),
|
| registry_(std::move(registry)),
|
| + controller_(new ConnectionFilterController(this)),
|
| weak_factory_(this) {
|
| // Registration of this filter may race with browser shutdown, in which case
|
| // it's possible for this filter to be destroyed on the main thread. This
|
| @@ -483,6 +512,14 @@ class RenderProcessHostImpl::ConnectionFilterImpl : public ConnectionFilter {
|
|
|
| ~ConnectionFilterImpl() override {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| + controller_->Detach();
|
| + }
|
| +
|
| + scoped_refptr<ConnectionFilterController> controller() { return controller_; }
|
| +
|
| + void Disable() {
|
| + base::AutoLock lock(enabled_lock_);
|
| + enabled_ = false;
|
| }
|
|
|
| private:
|
| @@ -498,6 +535,10 @@ class RenderProcessHostImpl::ConnectionFilterImpl : public ConnectionFilter {
|
| return false;
|
| }
|
|
|
| + base::AutoLock lock(enabled_lock_);
|
| + if (!enabled_)
|
| + return false;
|
| +
|
| std::set<std::string> interface_names;
|
| registry_->GetInterfaceNames(&interface_names);
|
| for (auto& interface_name : interface_names) {
|
| @@ -516,17 +557,32 @@ class RenderProcessHostImpl::ConnectionFilterImpl : public ConnectionFilter {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| shell::mojom::InterfaceProvider* provider = registry_.get();
|
| - provider->GetInterface(interface_name, std::move(handle));
|
| +
|
| + base::AutoLock lock(enabled_lock_);
|
| + if (enabled_)
|
| + provider->GetInterface(interface_name, std::move(handle));
|
| }
|
|
|
| base::ThreadChecker thread_checker_;
|
| shell::Identity child_identity_;
|
| std::unique_ptr<shell::InterfaceRegistry> registry_;
|
| + scoped_refptr<ConnectionFilterController> controller_;
|
| +
|
| + // Guards |enabled_|.
|
| + base::Lock enabled_lock_;
|
| + bool enabled_ = true;
|
| +
|
| base::WeakPtrFactory<ConnectionFilterImpl> weak_factory_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ConnectionFilterImpl);
|
| };
|
|
|
| +void RenderProcessHostImpl::ConnectionFilterController::DisableFilter() {
|
| + base::AutoLock lock(lock_);
|
| + if (filter_)
|
| + filter_->Disable();
|
| +}
|
| +
|
| base::MessageLoop*
|
| RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
|
| return g_in_process_thread;
|
| @@ -631,6 +687,8 @@ RenderProcessHostImpl::RenderProcessHostImpl(
|
| never_signaled_(base::WaitableEvent::ResetPolicy::MANUAL,
|
| base::WaitableEvent::InitialState::NOT_SIGNALED),
|
| #endif
|
| + instance_weak_factory_(
|
| + new base::WeakPtrFactory<RenderProcessHostImpl>(this)),
|
| weak_factory_(this) {
|
| widget_helper_ = new RenderWidgetHelper();
|
|
|
| @@ -1116,44 +1174,41 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
|
| interface_registry_android_.get());
|
| #endif
|
|
|
| - scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner =
|
| - BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
|
| #if !defined(OS_ANDROID)
|
| - registry->AddInterface(base::Bind(&device::BatteryMonitorImpl::Create),
|
| - ui_task_runner);
|
| + AddUIThreadInterface(
|
| + registry.get(), base::Bind(&device::BatteryMonitorImpl::Create));
|
| #endif
|
| - registry->AddInterface(
|
| + AddUIThreadInterface(
|
| + registry.get(),
|
| base::Bind(&PermissionServiceContext::CreateService,
|
| - base::Unretained(permission_service_context_.get())),
|
| - ui_task_runner);
|
| + base::Unretained(permission_service_context_.get())));
|
| // TODO(mcasas): finalize arguments.
|
| - registry->AddInterface(base::Bind(&ImageCaptureImpl::Create),
|
| - ui_task_runner);
|
| - registry->AddInterface(base::Bind(&OffscreenCanvasSurfaceImpl::Create),
|
| - ui_task_runner);
|
| - registry->AddInterface(
|
| + AddUIThreadInterface(registry.get(), base::Bind(&ImageCaptureImpl::Create));
|
| + AddUIThreadInterface(registry.get(),
|
| + base::Bind(&OffscreenCanvasSurfaceImpl::Create));
|
| + AddUIThreadInterface(
|
| + registry.get(),
|
| base::Bind(&BackgroundSyncContext::CreateService,
|
| base::Unretained(
|
| - storage_partition_impl_->GetBackgroundSyncContext())),
|
| - ui_task_runner);
|
| - registry->AddInterface(
|
| + storage_partition_impl_->GetBackgroundSyncContext())));
|
| + AddUIThreadInterface(
|
| + registry.get(),
|
| base::Bind(&PlatformNotificationContextImpl::CreateService,
|
| base::Unretained(
|
| storage_partition_impl_->GetPlatformNotificationContext()),
|
| - GetID()),
|
| - ui_task_runner);
|
| - registry->AddInterface(
|
| + GetID()));
|
| + AddUIThreadInterface(
|
| + registry.get(),
|
| base::Bind(&RenderProcessHostImpl::CreateStoragePartitionService,
|
| - base::Unretained(this)),
|
| - ui_task_runner);
|
| - registry->AddInterface(
|
| + base::Unretained(this)));
|
| + AddUIThreadInterface(
|
| + registry.get(),
|
| base::Bind(&BroadcastChannelProvider::Connect,
|
| base::Unretained(
|
| - storage_partition_impl_->GetBroadcastChannelProvider())),
|
| - ui_task_runner);
|
| + storage_partition_impl_->GetBroadcastChannelProvider())));
|
| if (memory_coordinator::IsEnabled()) {
|
| - registry->AddInterface(base::Bind(&CreateMemoryCoordinatorHandle, GetID()),
|
| - ui_task_runner);
|
| + AddUIThreadInterface(
|
| + registry.get(), base::Bind(&CreateMemoryCoordinatorHandle, GetID()));
|
| }
|
|
|
| scoped_refptr<base::SingleThreadTaskRunner> file_task_runner =
|
| @@ -1175,9 +1230,9 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
|
|
|
| // This is to support usage of WebSockets in cases in which there is no
|
| // associated RenderFrame (e.g., Shared Workers).
|
| - registry->AddInterface(
|
| - base::Bind(&WebSocketManager::CreateWebSocket, GetID(), MSG_ROUTING_NONE),
|
| - ui_task_runner);
|
| + AddUIThreadInterface(
|
| + registry.get(), base::Bind(&WebSocketManager::CreateWebSocket, GetID(),
|
| + MSG_ROUTING_NONE));
|
|
|
| GetContentClient()->browser()->ExposeInterfacesToRenderer(registry.get(),
|
| this);
|
| @@ -1187,7 +1242,8 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
|
| std::unique_ptr<ConnectionFilterImpl> connection_filter(
|
| new ConnectionFilterImpl(mojo_child_connection_->child_identity(),
|
| std::move(registry)));
|
| - connection_filter_ =
|
| + connection_filter_controller_ = connection_filter->controller();
|
| + connection_filter_id_ =
|
| mojo_shell_connection->AddConnectionFilter(std::move(connection_filter));
|
| }
|
|
|
| @@ -1987,11 +2043,13 @@ void RenderProcessHostImpl::Cleanup() {
|
| NOTIFICATION_RENDERER_PROCESS_TERMINATED,
|
| Source<RenderProcessHost>(this), NotificationService::NoDetails());
|
|
|
| - if (connection_filter_ != MojoShellConnection::kInvalidConnectionFilterId) {
|
| + if (connection_filter_id_ !=
|
| + MojoShellConnection::kInvalidConnectionFilterId) {
|
| MojoShellConnection* mojo_shell_connection =
|
| BrowserContext::GetMojoShellConnectionFor(browser_context_);
|
| - mojo_shell_connection->RemoveConnectionFilter(connection_filter_);
|
| - connection_filter_ = MojoShellConnection::kInvalidConnectionFilterId;
|
| + connection_filter_controller_->DisableFilter();
|
| + mojo_shell_connection->RemoveConnectionFilter(connection_filter_id_);
|
| + connection_filter_id_ = MojoShellConnection::kInvalidConnectionFilterId;
|
| }
|
|
|
| #ifndef NDEBUG
|
| @@ -2020,6 +2078,9 @@ void RenderProcessHostImpl::Cleanup() {
|
| // Remove ourself from the list of renderer processes so that we can't be
|
| // reused in between now and when the Delete task runs.
|
| UnregisterHost(GetID());
|
| +
|
| + instance_weak_factory_.reset(
|
| + new base::WeakPtrFactory<RenderProcessHostImpl>(this));
|
| }
|
| }
|
|
|
|
|