Commit 00150c1b authored by sammc's avatar sammc Committed by Commit bot

Detect and clean up discarded mojo connections to deleted RenderFrames.

Currently, if a RenderFrame is deleted before the
ExchangeServiceProviders message is received in the renderer, the
message pipe handles contained in that message are retained, waiting for
a RenderFrame that has already been deleted. This changes
RenderThreadImpl::PendingRenderFrameConnect to detect when the browser
closes its handles to those message pipes and clean itself up when that
occurs.

BUG=457722

Review URL: https://codereview.chromium.org/1005893002

Cr-Commit-Position: refs/heads/master@{#320690}
parent cf78c4d6
......@@ -874,9 +874,10 @@ void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) {
scoped_refptr<PendingRenderFrameConnect> connection(it->second);
mojo::InterfaceRequest<mojo::ServiceProvider> services(
connection->services.Pass());
connection->services().Pass());
mojo::ServiceProviderPtr exposed_services(
connection->exposed_services.Pass());
connection->exposed_services().Pass());
exposed_services.set_error_handler(nullptr);
pending_render_frame_connects_.erase(it);
frame->BindServiceRegistry(services.Pass(), exposed_services.Pass());
......@@ -911,8 +912,7 @@ void RenderThreadImpl::RegisterPendingRenderFrameConnect(
pending_render_frame_connects_.insert(std::make_pair(
routing_id,
make_scoped_refptr(new PendingRenderFrameConnect(
services.Pass(),
exposed_services.Pass()))));
routing_id, services.Pass(), exposed_services.Pass()))));
CHECK(result.second) << "Inserting a duplicate item.";
}
......@@ -1790,13 +1790,26 @@ void RenderThreadImpl::WidgetRestored() {
}
RenderThreadImpl::PendingRenderFrameConnect::PendingRenderFrameConnect(
int routing_id,
mojo::InterfaceRequest<mojo::ServiceProvider> services,
mojo::ServiceProviderPtr exposed_services)
: services(services.Pass()),
exposed_services(exposed_services.Pass()) {
: routing_id_(routing_id),
services_(services.Pass()),
exposed_services_(exposed_services.Pass()) {
// The RenderFrame may be deleted before the ExchangeServiceProviders message
// is received. In that case, the RenderFrameHost should close the connection,
// which is detected by setting an error handler on |exposed_services_|.
exposed_services_.set_error_handler(this);
}
RenderThreadImpl::PendingRenderFrameConnect::~PendingRenderFrameConnect() {
}
void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() {
size_t erased =
RenderThreadImpl::current()->pending_render_frame_connects_.erase(
routing_id_);
DCHECK_EQ(1u, erased);
}
} // namespace content
......@@ -606,19 +606,31 @@ class CONTENT_EXPORT RenderThreadImpl
bool is_elastic_overscroll_enabled_;
unsigned use_image_texture_target_;
struct PendingRenderFrameConnect
: public base::RefCounted<PendingRenderFrameConnect> {
class PendingRenderFrameConnect
: public base::RefCounted<PendingRenderFrameConnect>,
public mojo::ErrorHandler {
public:
PendingRenderFrameConnect(
int routing_id,
mojo::InterfaceRequest<mojo::ServiceProvider> services,
mojo::ServiceProviderPtr exposed_services);
mojo::InterfaceRequest<mojo::ServiceProvider> services;
mojo::ServiceProviderPtr exposed_services;
mojo::InterfaceRequest<mojo::ServiceProvider>& services() {
return services_;
}
mojo::ServiceProviderPtr& exposed_services() { return exposed_services_; }
private:
friend class base::RefCounted<PendingRenderFrameConnect>;
~PendingRenderFrameConnect();
~PendingRenderFrameConnect() override;
void OnConnectionError() override;
int routing_id_;
mojo::InterfaceRequest<mojo::ServiceProvider> services_;
mojo::ServiceProviderPtr exposed_services_;
};
typedef std::map<int, scoped_refptr<PendingRenderFrameConnect>>
......
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