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); |
}; |