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
;
20 template <typename Interface
>
21 class InterfacePtrState
{
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).
33 Interface
* instance() {
34 ConfigureProxyIfNecessary();
36 // This will be NULL if the object is not bound.
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
) {
49 MOJO_DCHECK(!router_
);
50 MOJO_DCHECK(!handle_
.is_valid());
51 MOJO_DCHECK(!waiter_
);
53 handle_
= handle
.Pass();
57 bool WaitForIncomingMethodCall() {
58 ConfigureProxyIfNecessary();
61 return router_
->WaitForIncomingMessage();
64 ScopedMessagePipeHandle
PassMessagePipe() {
66 return router_
->PassMessagePipe();
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();
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();
91 router_
->set_error_handler(error_handler
);
94 Router
* router_for_testing() {
95 ConfigureProxyIfNecessary();
100 class ProxyWithStub
: public Interface::Proxy_
{
102 explicit ProxyWithStub(MessageReceiverWithResponder
* receiver
)
103 : Interface::Proxy_(receiver
) {
105 typename
Interface::Client::Stub_ stub
;
107 MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub
);
110 void ConfigureProxyIfNecessary() {
111 // The proxy has been configured.
113 MOJO_DCHECK(router_
);
116 // The object hasn't been bound.
118 MOJO_DCHECK(!handle_
.is_valid());
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_
);
130 ProxyWithStub
* proxy
= new ProxyWithStub(router_
);
131 router_
->set_incoming_receiver(&proxy
->stub
);
136 ProxyWithStub
* proxy_
;
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
151 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_