Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Unified Diff: content/browser/renderer_host/render_process_host_impl.cc

Issue 2255493004: Synchronously disable ConnectionFilterImpl when its RPHI cleans up (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix-connection-filter-race
Patch Set: . Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/renderer_host/render_process_host_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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));
}
}
« no previous file with comments | « content/browser/renderer_host/render_process_host_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698