| Index: mojo/public/cpp/bindings/lib/interface_ptr_internal.h
|
| diff --git a/mojo/public/cpp/bindings/lib/interface_ptr_internal.h b/mojo/public/cpp/bindings/lib/interface_ptr_internal.h
|
| index 0a0b907697a6986041fdd7229f4c4932d1d1e0a5..adf7f603fda5716db3e76d1d02f041a323523364 100644
|
| --- a/mojo/public/cpp/bindings/lib/interface_ptr_internal.h
|
| +++ b/mojo/public/cpp/bindings/lib/interface_ptr_internal.h
|
| @@ -11,7 +11,8 @@
|
| #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/environment/environment.h"
|
| +
|
| +struct MojoAsyncWaiter;
|
|
|
| namespace mojo {
|
| namespace internal {
|
| @@ -19,7 +20,7 @@ namespace internal {
|
| template <typename Interface>
|
| class InterfacePtrState {
|
| public:
|
| - InterfacePtrState() : proxy_(NULL), router_(NULL) {}
|
| + InterfacePtrState() : proxy_(NULL), router_(NULL), waiter_(NULL) {}
|
|
|
| ~InterfacePtrState() {
|
| // Destruction order matters here. We delete |proxy_| first, even though
|
| @@ -29,43 +30,68 @@ class InterfacePtrState {
|
| delete router_;
|
| }
|
|
|
| - Interface* instance() const { return proxy_; }
|
| + Interface* instance() {
|
| + ConfigureProxyIfNecessary();
|
|
|
| - Router* router() const { return router_; }
|
| + // This will be NULL if the object is not bound.
|
| + return proxy_;
|
| + }
|
|
|
| void Swap(InterfacePtrState* other) {
|
| std::swap(other->proxy_, proxy_);
|
| std::swap(other->router_, router_);
|
| + handle_.swap(other->handle_);
|
| + std::swap(other->waiter_, waiter_);
|
| }
|
|
|
| - void ConfigureProxy(
|
| - ScopedMessagePipeHandle handle,
|
| - const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
|
| + void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
|
| assert(!proxy_);
|
| assert(!router_);
|
| + assert(!handle_.is_valid());
|
| + assert(!waiter_);
|
|
|
| - FilterChain filters;
|
| - filters.Append<MessageHeaderValidator>();
|
| - filters.Append<typename Interface::Client::RequestValidator_>();
|
| - filters.Append<typename Interface::ResponseValidator_>();
|
| -
|
| - router_ = new Router(handle.Pass(), filters.Pass(), waiter);
|
| - ProxyWithStub* proxy = new ProxyWithStub(router_);
|
| - router_->set_incoming_receiver(&proxy->stub);
|
| -
|
| - proxy_ = proxy;
|
| + handle_ = handle.Pass();
|
| + waiter_ = waiter;
|
| }
|
|
|
| bool WaitForIncomingMethodCall() {
|
| + ConfigureProxyIfNecessary();
|
| +
|
| assert(router_);
|
| return router_->WaitForIncomingMessage();
|
| }
|
|
|
| + ScopedMessagePipeHandle PassMessagePipe() {
|
| + if (router_)
|
| + return router_->PassMessagePipe();
|
| +
|
| + waiter_ = NULL;
|
| + return handle_.Pass();
|
| + }
|
| +
|
| void set_client(typename Interface::Client* client) {
|
| + ConfigureProxyIfNecessary();
|
| +
|
| assert(proxy_);
|
| proxy_->stub.set_sink(client);
|
| }
|
|
|
| + bool encountered_error() const {
|
| + return router_ ? router_->encountered_error() : false;
|
| + }
|
| +
|
| + void set_error_handler(ErrorHandler* error_handler) {
|
| + ConfigureProxyIfNecessary();
|
| +
|
| + assert(router_);
|
| + router_->set_error_handler(error_handler);
|
| + }
|
| +
|
| + Router* router_for_testing() {
|
| + ConfigureProxyIfNecessary();
|
| + return router_;
|
| + }
|
| +
|
| private:
|
| class ProxyWithStub : public Interface::Proxy_ {
|
| public:
|
| @@ -77,9 +103,41 @@ class InterfacePtrState {
|
| MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
|
| };
|
|
|
| + void ConfigureProxyIfNecessary() {
|
| + // The proxy has been configured.
|
| + if (proxy_) {
|
| + assert(router_);
|
| + return;
|
| + }
|
| + // The object hasn't been bound.
|
| + if (!waiter_) {
|
| + assert(!handle_.is_valid());
|
| + return;
|
| + }
|
| +
|
| + FilterChain filters;
|
| + filters.Append<MessageHeaderValidator>();
|
| + filters.Append<typename Interface::Client::RequestValidator_>();
|
| + filters.Append<typename Interface::ResponseValidator_>();
|
| +
|
| + router_ = new Router(handle_.Pass(), filters.Pass(), waiter_);
|
| + waiter_ = NULL;
|
| +
|
| + ProxyWithStub* proxy = new ProxyWithStub(router_);
|
| + router_->set_incoming_receiver(&proxy->stub);
|
| +
|
| + proxy_ = proxy;
|
| + }
|
| +
|
| ProxyWithStub* proxy_;
|
| Router* router_;
|
|
|
| + // |proxy_| and |router_| are not initialized until read/write with the
|
| + // message pipe handle is needed. Before that, |handle_| and |waiter_| store
|
| + // the arguments of Bind().
|
| + ScopedMessagePipeHandle handle_;
|
| + const MojoAsyncWaiter* waiter_;
|
| +
|
| MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
|
| };
|
|
|
|
|