OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_ | |
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_ | |
7 | |
8 #include <algorithm> // For |std::swap()|. | |
9 | |
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" | |
14 | |
15 struct MojoAsyncWaiter; | |
16 | |
17 namespace mojo { | |
18 namespace internal { | |
19 | |
20 template <typename Interface> | |
21 class InterfacePtrState { | |
22 public: | |
23 InterfacePtrState() : proxy_(nullptr), router_(nullptr), waiter_(nullptr) {} | |
24 | |
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_; | |
31 } | |
32 | |
33 Interface* instance() { | |
34 ConfigureProxyIfNecessary(); | |
35 | |
36 // This will be null if the object is not bound. | |
37 return proxy_; | |
38 } | |
39 | |
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_); | |
45 } | |
46 | |
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_); | |
52 | |
53 handle_ = handle.Pass(); | |
54 waiter_ = waiter; | |
55 } | |
56 | |
57 bool WaitForIncomingMethodCall() { | |
58 ConfigureProxyIfNecessary(); | |
59 | |
60 MOJO_DCHECK(router_); | |
61 return router_->WaitForIncomingMessage(); | |
62 } | |
63 | |
64 ScopedMessagePipeHandle PassMessagePipe() { | |
65 if (router_) | |
66 return router_->PassMessagePipe(); | |
67 | |
68 waiter_ = nullptr; | |
69 return handle_.Pass(); | |
70 } | |
71 | |
72 bool is_bound() const { return handle_.is_valid() || router_; } | |
73 | |
74 void set_client(typename Interface::Client* client) { | |
75 ConfigureProxyIfNecessary(); | |
76 | |
77 MOJO_DCHECK(proxy_); | |
78 proxy_->stub.set_sink(client); | |
79 } | |
80 | |
81 bool encountered_error() const { | |
82 return router_ ? router_->encountered_error() : false; | |
83 } | |
84 | |
85 void set_error_handler(ErrorHandler* error_handler) { | |
86 ConfigureProxyIfNecessary(); | |
87 | |
88 MOJO_DCHECK(router_); | |
89 router_->set_error_handler(error_handler); | |
90 } | |
91 | |
92 Router* router_for_testing() { | |
93 ConfigureProxyIfNecessary(); | |
94 return router_; | |
95 } | |
96 | |
97 private: | |
98 class ProxyWithStub : public Interface::Proxy_ { | |
99 public: | |
100 explicit ProxyWithStub(MessageReceiverWithResponder* receiver) | |
101 : Interface::Proxy_(receiver) {} | |
102 typename Interface::Client::Stub_ stub; | |
103 | |
104 private: | |
105 MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub); | |
106 }; | |
107 | |
108 void ConfigureProxyIfNecessary() { | |
109 // The proxy has been configured. | |
110 if (proxy_) { | |
111 MOJO_DCHECK(router_); | |
112 return; | |
113 } | |
114 // The object hasn't been bound. | |
115 if (!waiter_) { | |
116 MOJO_DCHECK(!handle_.is_valid()); | |
117 return; | |
118 } | |
119 | |
120 FilterChain filters; | |
121 filters.Append<MessageHeaderValidator>(); | |
122 filters.Append<typename Interface::Client::RequestValidator_>(); | |
123 filters.Append<typename Interface::ResponseValidator_>(); | |
124 | |
125 router_ = new Router(handle_.Pass(), filters.Pass(), waiter_); | |
126 waiter_ = nullptr; | |
127 | |
128 ProxyWithStub* proxy = new ProxyWithStub(router_); | |
129 router_->set_incoming_receiver(&proxy->stub); | |
130 | |
131 proxy_ = proxy; | |
132 } | |
133 | |
134 ProxyWithStub* proxy_; | |
135 Router* router_; | |
136 | |
137 // |proxy_| and |router_| are not initialized until read/write with the | |
138 // message pipe handle is needed. Before that, |handle_| and |waiter_| store | |
139 // the arguments of Bind(). | |
140 ScopedMessagePipeHandle handle_; | |
141 const MojoAsyncWaiter* waiter_; | |
142 | |
143 MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); | |
144 }; | |
145 | |
146 } // namespace internal | |
147 } // namespace mojo | |
148 | |
149 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_ | |
OLD | NEW |