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

Unified Diff: mojo/public/cpp/bindings/lib/binding_state.h

Issue 1473273003: Mojo C++ bindings: InterfacePtr<T> and Binding<T> use MultiplexRouter when T passes associated inte… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
Index: mojo/public/cpp/bindings/lib/binding_state.h
diff --git a/mojo/public/cpp/bindings/lib/binding_state.h b/mojo/public/cpp/bindings/lib/binding_state.h
new file mode 100644
index 0000000000000000000000000000000000000000..d6f4711ef4f0f9c05cee20687cd5f152cf31c291
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/binding_state.h
@@ -0,0 +1,206 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "mojo/public/c/environment/async_waiter.h"
+#include "mojo/public/cpp/bindings/associated_group.h"
+#include "mojo/public/cpp/bindings/callback.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_ptr_info.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/lib/filter_chain.h"
+#include "mojo/public/cpp/bindings/lib/interface_endpoint_client.h"
+#include "mojo/public/cpp/bindings/lib/interface_id.h"
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
+#include "mojo/public/cpp/bindings/lib/multiplex_router.h"
+#include "mojo/public/cpp/bindings/lib/router.h"
+#include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename Interface, bool use_multiplex_router>
+class BindingState;
+
+// Uses a single-threaded, dedicated router. If |Interface| doesn't have any
+// methods to pass associated interface pointers or requests, there won't be
+// multiple interfaces running on the underlying message pipe. In that case, we
+// can use this specialization to reduce cost.
+template <typename Interface>
+class BindingState<Interface, false> {
+ public:
+ explicit BindingState(Interface* impl) : impl_(impl) {
+ stub_.set_sink(impl_);
+ }
+
+ ~BindingState() {
+ if (router_)
+ Close();
+ }
+
+ void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
+ DCHECK(!router_);
+ internal::FilterChain filters;
+ filters.Append<internal::MessageHeaderValidator>();
+ filters.Append<typename Interface::RequestValidator_>();
+
+ router_ = new internal::Router(handle.Pass(), filters.Pass(), waiter);
+ router_->set_incoming_receiver(&stub_);
+ router_->set_connection_error_handler(
+ [this]() { connection_error_handler_.Run(); });
+ }
+
+ void PauseIncomingMethodCallProcessing() {
+ DCHECK(router_);
+ router_->PauseIncomingMethodCallProcessing();
+ }
+ void ResumeIncomingMethodCallProcessing() {
+ DCHECK(router_);
+ router_->ResumeIncomingMethodCallProcessing();
+ }
+
+ bool WaitForIncomingMethodCall(
+ MojoDeadline deadline = MOJO_DEADLINE_INDEFINITE) {
+ DCHECK(router_);
+ return router_->WaitForIncomingMessage(deadline);
+ }
+
+ void Close() {
+ DCHECK(router_);
+ router_->CloseMessagePipe();
+ DestroyRouter();
+ }
+
+ InterfaceRequest<Interface> Unbind() {
+ InterfaceRequest<Interface> request =
+ MakeRequest<Interface>(router_->PassMessagePipe());
+ DestroyRouter();
+ return request.Pass();
+ }
+
+ void set_connection_error_handler(const Closure& error_handler) {
+ connection_error_handler_ = error_handler;
+ }
+
+ Interface* impl() { return impl_; }
+
+ bool is_bound() const { return !!router_; }
+
+ MessagePipeHandle handle() const {
+ DCHECK(is_bound());
+ return router_->handle();
+ }
+
+ AssociatedGroup* associated_group() { return nullptr; }
+
+ void EnableTestingMode() {
+ DCHECK(is_bound());
+ router_->EnableTestingMode();
+ }
+
+ private:
+ void DestroyRouter() {
+ router_->set_connection_error_handler(Closure());
+ delete router_;
+ router_ = nullptr;
+ }
+
+ internal::Router* router_ = nullptr;
+ typename Interface::Stub_ stub_;
+ Interface* impl_;
+ Closure connection_error_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(BindingState);
+};
+
+// Uses a multiplexing router. If |Interface| has methods to pass associated
+// interface pointers or requests, this specialization should be used.
+template <typename Interface>
+class BindingState<Interface, true> {
+ public:
+ explicit BindingState(Interface* impl) : impl_(impl) {
+ stub_.set_sink(impl_);
+ }
+
+ ~BindingState() {
+ if (router_)
+ Close();
+ }
+
+ void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
+ DCHECK(!router_);
+
+ router_ = new internal::MultiplexRouter(false, handle.Pass(), waiter);
+ endpoint_client_.reset(new internal::InterfaceEndpointClient(
+ router_->CreateLocalEndpointHandle(internal::kMasterInterfaceId),
+ &stub_, make_scoped_ptr(new typename Interface::RequestValidator_())));
+
+ endpoint_client_->set_connection_error_handler(
+ [this]() { connection_error_handler_.Run(); });
+ }
+
+ void Close() {
+ DCHECK(router_);
+ endpoint_client_.reset();
+ router_->CloseMessagePipe();
+ router_ = nullptr;
+ }
+
+ InterfaceRequest<Interface> Unbind() {
+ endpoint_client_.reset();
+ InterfaceRequest<Interface> request =
+ MakeRequest<Interface>(router_->PassMessagePipe());
+ router_ = nullptr;
+ return request.Pass();
+ }
+
+ void set_connection_error_handler(const Closure& error_handler) {
+ connection_error_handler_ = error_handler;
+ }
+
+ Interface* impl() { return impl_; }
+
+ bool is_bound() const { return !!router_; }
+
+ MessagePipeHandle handle() const {
+ DCHECK(is_bound());
+ return router_->handle();
+ }
+
+ AssociatedGroup* associated_group() {
+ return endpoint_client_ ? endpoint_client_->associated_group() : nullptr;
+ }
+
+ void EnableTestingMode() {
+ DCHECK(is_bound());
+ router_->EnableTestingMode();
+ }
+
+ // Intentionally not defined:
+ // void PauseIncomingMethodCallProcessing();
+ // void ResumeIncomingMethodCallProcessing();
+ // bool WaitForIncomingMethodCall(MojoDeadline deadline);
+
+ private:
+ scoped_refptr<internal::MultiplexRouter> router_;
+ scoped_ptr<internal::InterfaceEndpointClient> endpoint_client_;
+
+ typename Interface::Stub_ stub_;
+ Interface* impl_;
+ Closure connection_error_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(BindingState);
+};
+
+} // namesapce internal
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDING_STATE_H_
« no previous file with comments | « mojo/public/cpp/bindings/lib/associated_interface_ptr_state.h ('k') | mojo/public/cpp/bindings/lib/interface_ptr_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698