Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / mojo / public / cpp / bindings / lib / interface_ptr_internal.h
blob7e9a26286a7637ccc2d5d2bce2ff641139540aa4
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
8 #include <algorithm> // For |std::swap()|.
10 #include "mojo/public/cpp/bindings/lib/filter_chain.h"
11 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
12 #include "mojo/public/cpp/bindings/lib/router.h"
13 #include "mojo/public/cpp/environment/logging.h"
15 struct MojoAsyncWaiter;
17 namespace mojo {
18 namespace internal {
20 template <typename Interface>
21 class InterfacePtrState {
22 public:
23 InterfacePtrState() : proxy_(NULL), router_(NULL), waiter_(NULL) {}
25 ~InterfacePtrState() {
26 // Destruction order matters here. We delete |proxy_| first, even though
27 // |router_| may have a reference to it, so that |~Interface| may have a
28 // shot at generating new outbound messages (ie, invoking client methods).
29 delete proxy_;
30 delete router_;
33 Interface* instance() {
34 ConfigureProxyIfNecessary();
36 // This will be NULL if the object is not bound.
37 return proxy_;
40 void Swap(InterfacePtrState* other) {
41 std::swap(other->proxy_, proxy_);
42 std::swap(other->router_, router_);
43 handle_.swap(other->handle_);
44 std::swap(other->waiter_, waiter_);
47 void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
48 MOJO_DCHECK(!proxy_);
49 MOJO_DCHECK(!router_);
50 MOJO_DCHECK(!handle_.is_valid());
51 MOJO_DCHECK(!waiter_);
53 handle_ = handle.Pass();
54 waiter_ = waiter;
57 bool WaitForIncomingMethodCall() {
58 ConfigureProxyIfNecessary();
60 MOJO_DCHECK(router_);
61 return router_->WaitForIncomingMessage();
64 ScopedMessagePipeHandle PassMessagePipe() {
65 if (router_)
66 return router_->PassMessagePipe();
68 waiter_ = NULL;
69 return handle_.Pass();
72 bool is_bound() const {
73 return handle_.is_valid() || router_;
76 void set_client(typename Interface::Client* client) {
77 ConfigureProxyIfNecessary();
79 MOJO_DCHECK(proxy_);
80 proxy_->stub.set_sink(client);
83 bool encountered_error() const {
84 return router_ ? router_->encountered_error() : false;
87 void set_error_handler(ErrorHandler* error_handler) {
88 ConfigureProxyIfNecessary();
90 MOJO_DCHECK(router_);
91 router_->set_error_handler(error_handler);
94 Router* router_for_testing() {
95 ConfigureProxyIfNecessary();
96 return router_;
99 private:
100 class ProxyWithStub : public Interface::Proxy_ {
101 public:
102 explicit ProxyWithStub(MessageReceiverWithResponder* receiver)
103 : Interface::Proxy_(receiver) {
105 typename Interface::Client::Stub_ stub;
106 private:
107 MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
110 void ConfigureProxyIfNecessary() {
111 // The proxy has been configured.
112 if (proxy_) {
113 MOJO_DCHECK(router_);
114 return;
116 // The object hasn't been bound.
117 if (!waiter_) {
118 MOJO_DCHECK(!handle_.is_valid());
119 return;
122 FilterChain filters;
123 filters.Append<MessageHeaderValidator>();
124 filters.Append<typename Interface::Client::RequestValidator_>();
125 filters.Append<typename Interface::ResponseValidator_>();
127 router_ = new Router(handle_.Pass(), filters.Pass(), waiter_);
128 waiter_ = NULL;
130 ProxyWithStub* proxy = new ProxyWithStub(router_);
131 router_->set_incoming_receiver(&proxy->stub);
133 proxy_ = proxy;
136 ProxyWithStub* proxy_;
137 Router* router_;
139 // |proxy_| and |router_| are not initialized until read/write with the
140 // message pipe handle is needed. Before that, |handle_| and |waiter_| store
141 // the arguments of Bind().
142 ScopedMessagePipeHandle handle_;
143 const MojoAsyncWaiter* waiter_;
145 MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
148 } // namespace internal
149 } // namespace mojo
151 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_