Index: mojo/public/cpp/bindings/strong_connector.h |
diff --git a/mojo/public/cpp/bindings/strong_connector.h b/mojo/public/cpp/bindings/strong_connector.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..543db100eeb55b04d26c57d68bba326f482a5db6 |
--- /dev/null |
+++ b/mojo/public/cpp/bindings/strong_connector.h |
@@ -0,0 +1,94 @@ |
+#ifndef MOJO_PUBLIC_CPP_BINDINGS_STRONG_CONNECTOR_H_ |
+#define MOJO_PUBLIC_CPP_BINDINGS_STRONG_CONNECTOR_H_ |
+ |
+#include "mojo/public/c/environment/async_waiter.h" |
+#include "mojo/public/cpp/bindings/error_handler.h" |
+#include "mojo/public/cpp/bindings/lib/filter_chain.h" |
+#include "mojo/public/cpp/bindings/lib/message_header_validator.h" |
+#include "mojo/public/cpp/bindings/lib/router.h" |
+#include "mojo/public/cpp/system/core.h" |
+ |
+namespace mojo { |
+ |
+// This connects an interface implementation strongly to a pipe. When a |
+// connection error is detected the implementation is deleted. Deleting the |
+// connector also closes the pipe. |
+// |
+// Example of an implementation that is always bound strongly to a pipe |
+// |
+// class StronglyBound : public Foo { |
+// public: |
+// explicit StronglyBound(ScopedMessagePipeHandle handle) |
+// : connector_(this, handle.Pass()) {} |
+// |
+// // Foo implementation here |
+// |
+// private: |
+// StrongConnector<Foo> connector_; |
+// }; |
+// |
+template <typename Interface> |
+class StrongConnector : public ErrorHandler { |
+ typedef typename Interface::Client Client; |
+ |
+ public: |
+ explicit StrongConnector(Interface* impl) : impl_(impl) { |
+ stub_.set_sink(impl_); |
+ } |
+ |
+ StrongConnector( |
+ Interface* impl, |
+ ScopedMessagePipeHandle handle, |
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) |
+ : StrongConnector(impl) { |
+ stub_.set_sink(impl_); |
+ Bind(handle.Pass(), waiter); |
+ } |
+ |
+ virtual ~StrongConnector() { |
+ delete proxy_; |
+ if (router_) { |
+ router_->set_error_handler(nullptr); |
+ delete router_; |
+ } |
+ } |
+ |
+ void Bind( |
+ ScopedMessagePipeHandle handle, |
+ const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) { |
+ internal::FilterChain filters; |
+ filters.Append<internal::MessageHeaderValidator>(); |
+ filters.Append<typename Interface::RequestValidator_>(); |
+ filters.Append<typename Interface::Client::ResponseValidator_>(); |
+ |
+ router_ = new internal::Router(handle.Pass(), filters.Pass(), waiter); |
+ router_->set_incoming_receiver(&stub_); |
+ router_->set_error_handler(this); |
+ |
+ proxy_ = new typename Client::Proxy_(router_); |
+ } |
+ |
+ void set_error_handler(ErrorHandler* error_handler) { |
+ error_handler_ = error_handler; |
+ } |
+ |
+ // ErrorHandler implementation |
+ void OnConnectionError() override { |
+ if (error_handler_) |
+ error_handler_->OnConnectionError(); |
+ delete impl_; |
+ } |
+ |
+ typename Interface::Client* client() { return proxy_; } |
+ |
+ private: |
+ internal::Router* router_ = nullptr; |
+ typename Client::Proxy_* proxy_ = nullptr; |
+ typename Interface::Stub_ stub_; |
+ Interface* impl_; |
+ ErrorHandler* error_handler_ = nullptr; |
+}; |
+ |
+} // namespace mojo |
+ |
+#endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_CONNECTOR_H_ |