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

Unified Diff: sky/services/inspector/server.cc

Issue 711413005: Use WeakBindingSet to manage inspector connections (Closed) Base URL: git@github.com:domokit/mojo.git@connector
Patch Set: Created 6 years, 1 month 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 | « mojo/public/cpp/bindings/binding.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/services/inspector/server.cc
diff --git a/sky/services/inspector/server.cc b/sky/services/inspector/server.cc
index 0963dd18b7e6bd614a4c3e2b03c281d97fb967c9..427517d2ed9fc886ab2147c2c6e03f77085fdb3b 100644
--- a/sky/services/inspector/server.cc
+++ b/sky/services/inspector/server.cc
@@ -2,12 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+
+#include "base/memory/weak_ptr.h"
#include "mojo/application/application_runner_chromium.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/application/interface_factory_impl.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_impl.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/server/http_server.h"
#include "net/socket/tcp_server_socket.h"
#include "sky/services/inspector/inspector.mojom.h"
@@ -16,102 +21,45 @@
namespace sky {
namespace inspector {
-// TODO(eseidel): None of this Impl nonsense is necessary: crbug.com/431963
-class InspectorServerImpl : public mojo::InterfaceImpl<InspectorServer> {
-public:
- class Delegate {
- public:
- virtual void Register(InspectorServerImpl* impl) = 0;
- virtual void Unregister(InspectorServerImpl* impl) = 0;
- virtual void Listen(int32_t port) = 0;
- };
- InspectorServerImpl(Delegate* delegate) : delegate_(delegate) {
- delegate_->Register(this);
- }
- virtual ~InspectorServerImpl() {
- delegate_->Unregister(this);
- }
-
- // InspectorServer:
- void Listen(int32_t port, const mojo::Callback<void()>& callback) override {
- delegate_->Listen(port);
- callback.Run();
- }
+namespace {
+const int kNotConnected = -1;
+}
- void OnShutdown() {
- delete this;
+// This provides a binding to an InspectorFrontend implementation that exposes a
jamesr 2014/11/12 20:47:38 this could be made generic and live somewhere more
+// weak pointer to itself. The binding itself is destroyed when a connection
+// error is detected or the binding is explicitly told to close.
+class FrontendWeakBinding : public mojo::ErrorHandler {
+ public:
+ FrontendWeakBinding(InspectorFrontend* frontend,
+ mojo::InterfaceRequest<InspectorFrontend> request)
+ : binding_(frontend, request.Pass()), weak_ptr_factory_(this) {
+ binding_.set_error_handler(this);
}
-private:
- // InterfaceImpl:
- void OnConnectionError() override {
- delete this; // crbug.com/431911
- }
+ void Close() { binding_.Close(); }
- Delegate* delegate_;
-};
+ InspectorFrontend::Client* client() { return binding_.client(); }
-class InspectorFrontendImpl : public mojo::InterfaceImpl<InspectorFrontend> {
- public:
- class Delegate {
- public:
- virtual void Register(InspectorFrontendImpl*) = 0;
- virtual void Unregister(InspectorFrontendImpl*) = 0;
- virtual void SendMessage(const mojo::String&) = 0;
- };
-
- InspectorFrontendImpl(Delegate* delegate);
- virtual ~InspectorFrontendImpl();
+ base::WeakPtr<FrontendWeakBinding> GetWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+ }
- void OnShutdown();
+ // mojo::ErrorHandler implementation.
+ void OnConnectionError() override { delete this; }
private:
- // InspectorFrontend:
- void SendMessage(const mojo::String& message) override;
-
- // InterfaceImpl:
- void OnConnectionError() override;
-
- Delegate* delegate_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(InspectorFrontendImpl);
+ mojo::Binding<InspectorFrontend> binding_;
+ base::WeakPtrFactory<FrontendWeakBinding> weak_ptr_factory_;
};
-InspectorFrontendImpl::InspectorFrontendImpl(Delegate* delegate)
- : delegate_(delegate) {
- delegate_->Register(this);
-}
-
-InspectorFrontendImpl::~InspectorFrontendImpl() {
- delegate_->Unregister(this);
-}
-
-void InspectorFrontendImpl::OnShutdown() {
- client()->OnDisconnect();
- delete this;
-}
-
-void InspectorFrontendImpl::OnConnectionError() {
- delete this; // crbug.com/431911
-}
-
-void InspectorFrontendImpl::SendMessage(const mojo::String& message) {
- delegate_->SendMessage(message);
-}
-
-
-namespace {
-const int kNotConnected = -1;
-}
-
class Server : public mojo::ApplicationDelegate,
- public InspectorFrontendImpl::Delegate,
- public InspectorServerImpl::Delegate,
- public mojo::InterfaceFactory<InspectorFrontend>,
- public mojo::InterfaceFactory<InspectorServer>,
- public net::HttpServer::Delegate {
+ public InspectorFrontend,
+ public InspectorServer,
+ public mojo::InterfaceFactory<InspectorFrontend>,
+ public mojo::InterfaceFactory<InspectorServer>,
+ public net::HttpServer::Delegate {
public:
- Server() : connection_id_(kNotConnected) {}
+ Server() : connection_id_(kNotConnected), server_binding_(this) {}
virtual ~Server();
private:
@@ -128,25 +76,20 @@ class Server : public mojo::ApplicationDelegate,
// InterfaceFactory<InspectorFrontend>:
void Create(mojo::ApplicationConnection* connection,
mojo::InterfaceRequest<InspectorFrontend> request) override {
- // Weak instead of strong, per crbug.com/431911
- WeakBindToRequest(new InspectorFrontendImpl(this), &request);
+ auto binding = new FrontendWeakBinding(this, request.Pass());
+ frontend_bindings_.push_back(binding->GetWeakPtr());
}
// InterfaceFactory<InspectorServer>:
void Create(mojo::ApplicationConnection* connection,
mojo::InterfaceRequest<InspectorServer> request) override {
- // Weak instead of strong, per crbug.com/431911
- WeakBindToRequest(new InspectorServerImpl(this), &request);
+ server_binding_.Bind(request.PassMessagePipe());
}
- // InspectorServerImpl::Delegate:
- void Register(InspectorServerImpl*) override;
- void Unregister(InspectorServerImpl*) override;
- void Listen(int32_t port) override;
+ // InspectorServer:
+ void Listen(int32_t port, const mojo::Closure& callback) override;
- // InspectorFrontendImpl::Delegate:
- void Register(InspectorFrontendImpl*) override;
- void Unregister(InspectorFrontendImpl*) override;
+ // InspectorFrontend:
void SendMessage(const mojo::String& message) override;
// net::HttpServer::Delegate:
@@ -160,23 +103,37 @@ class Server : public mojo::ApplicationDelegate,
void OnClose(int connection_id) override;
void CloseAllAgentConnections();
+ void ClearNullFrontendBindings();
int connection_id_;
scoped_ptr<net::HttpServer> web_server_;
- ObserverList<InspectorFrontendImpl> agents_;
- ObserverList<InspectorServerImpl> clients_;
+
+ std::vector<base::WeakPtr<FrontendWeakBinding>> frontend_bindings_;
+ mojo::Binding<InspectorServer> server_binding_;
DISALLOW_COPY_AND_ASSIGN(Server);
};
Server::~Server()
{
- FOR_EACH_OBSERVER(InspectorServerImpl, clients_, OnShutdown());
CloseAllAgentConnections();
}
void Server::CloseAllAgentConnections() {
- FOR_EACH_OBSERVER(InspectorFrontendImpl, agents_, OnShutdown());
+ for (const auto& it : frontend_bindings_) {
+ if (it.get())
+ it->Close();
+ }
+ frontend_bindings_.clear();
+}
+
+void Server::ClearNullFrontendBindings() {
+ frontend_bindings_.erase(
+ std::remove_if(frontend_bindings_.begin(), frontend_bindings_.end(),
+ [](const base::WeakPtr<FrontendWeakBinding>& p) {
+ return p.get() == nullptr;
+ }),
+ frontend_bindings_.end());
}
void Server::OnConnect(int connection_id) {
@@ -195,39 +152,30 @@ void Server::OnWebSocketRequest(
}
web_server_->AcceptWebSocket(connection_id, info);
connection_id_ = connection_id;
- FOR_EACH_OBSERVER(InspectorFrontendImpl, agents_, client()->OnConnect());
+ ClearNullFrontendBindings();
+ for (const auto& it : frontend_bindings_) {
+ it->client()->OnConnect();
+ }
}
void Server::OnWebSocketMessage(
int connection_id, const std::string& data) {
DCHECK_EQ(connection_id, connection_id_);
- FOR_EACH_OBSERVER(InspectorFrontendImpl, agents_, client()->OnMessage(data));
+ ClearNullFrontendBindings();
+ for (const auto& it : frontend_bindings_)
+ it->client()->OnMessage(data);
}
void Server::OnClose(int connection_id) {
if (connection_id != connection_id_)
return;
connection_id_ = kNotConnected;
- FOR_EACH_OBSERVER(InspectorFrontendImpl, agents_, client()->OnDisconnect());
-}
-
-void Server::Register(InspectorServerImpl* client) {
- clients_.AddObserver(client);
-}
-
-void Server::Unregister(InspectorServerImpl* client) {
- clients_.RemoveObserver(client);
-}
-
-void Server::Register(InspectorFrontendImpl* agent) {
- agents_.AddObserver(agent);
-}
-
-void Server::Unregister(InspectorFrontendImpl* agent) {
- agents_.RemoveObserver(agent);
+ ClearNullFrontendBindings();
+ for (const auto& it : frontend_bindings_)
+ it->client()->OnDisconnect();
}
-void Server::Listen(int32_t port) {
+void Server::Listen(int32_t port, const mojo::Closure& callback) {
CloseAllAgentConnections(); // Assume caller represents a new app.
// TODO(eseidel): Early-out here if we're already bound to the right port.
@@ -236,6 +184,7 @@ void Server::Listen(int32_t port) {
new net::TCPServerSocket(NULL, net::NetLog::Source()));
server_socket->ListenWithAddressAndPort("0.0.0.0", port, 1);
web_server_.reset(new net::HttpServer(server_socket.Pass(), this));
+ callback.Run();
}
void Server::SendMessage(const mojo::String& message) {
« no previous file with comments | « mojo/public/cpp/bindings/binding.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698