Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: mojo/public/cpp/bindings/lib/interface_ptr_internal.h

Issue 1473273003: Mojo C++ bindings: InterfacePtr<T> and Binding<T> use MultiplexRouter when T passes associated inte… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/callback.h"
11 #include "mojo/public/cpp/bindings/interface_ptr_info.h"
12 #include "mojo/public/cpp/bindings/lib/control_message_proxy.h"
13 #include "mojo/public/cpp/bindings/lib/filter_chain.h"
14 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
15 #include "mojo/public/cpp/bindings/lib/router.h"
16 #include "mojo/public/cpp/environment/logging.h"
17
18 struct MojoAsyncWaiter;
19
20 namespace mojo {
21 namespace internal {
22
23 template <typename Interface>
24 class InterfacePtrState {
25 public:
26 InterfacePtrState()
27 : proxy_(nullptr), router_(nullptr), waiter_(nullptr), version_(0u) {}
28
29 ~InterfacePtrState() {
30 // Destruction order matters here. We delete |proxy_| first, even though
31 // |router_| may have a reference to it, so that destructors for any request
32 // callbacks still pending can interact with the InterfacePtr.
33 delete proxy_;
34 delete router_;
35 }
36
37 Interface* instance() {
38 ConfigureProxyIfNecessary();
39
40 // This will be null if the object is not bound.
41 return proxy_;
42 }
43
44 uint32_t version() const { return version_; }
45
46 void QueryVersion(const Callback<void(uint32_t)>& callback) {
47 ConfigureProxyIfNecessary();
48
49 // It is safe to capture |this| because the callback won't be run after this
50 // object goes away.
51 auto callback_wrapper = [this, callback](uint32_t version) {
52 this->version_ = version;
53 callback.Run(version);
54 };
55
56 // Do a static cast in case the interface contains methods with the same
57 // name.
58 static_cast<ControlMessageProxy*>(proxy_)->QueryVersion(callback_wrapper);
59 }
60
61 void RequireVersion(uint32_t version) {
62 ConfigureProxyIfNecessary();
63
64 if (version <= version_)
65 return;
66
67 version_ = version;
68 // Do a static cast in case the interface contains methods with the same
69 // name.
70 static_cast<ControlMessageProxy*>(proxy_)->RequireVersion(version);
71 }
72
73 void Swap(InterfacePtrState* other) {
74 using std::swap;
75 swap(other->proxy_, proxy_);
76 swap(other->router_, router_);
77 handle_.swap(other->handle_);
78 swap(other->waiter_, waiter_);
79 swap(other->version_, version_);
80 }
81
82 void Bind(InterfacePtrInfo<Interface> info, const MojoAsyncWaiter* waiter) {
83 MOJO_DCHECK(!proxy_);
84 MOJO_DCHECK(!router_);
85 MOJO_DCHECK(!handle_.is_valid());
86 MOJO_DCHECK(!waiter_);
87 MOJO_DCHECK(version_ == 0u);
88 MOJO_DCHECK(info.is_valid());
89
90 handle_ = info.PassHandle();
91 waiter_ = waiter;
92 version_ = info.version();
93 }
94
95 bool WaitForIncomingResponse() {
96 ConfigureProxyIfNecessary();
97
98 MOJO_DCHECK(router_);
99 return router_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
100 }
101
102 // After this method is called, the object is in an invalid state and
103 // shouldn't be reused.
104 InterfacePtrInfo<Interface> PassInterface() {
105 return InterfacePtrInfo<Interface>(
106 router_ ? router_->PassMessagePipe() : handle_.Pass(), version_);
107 }
108
109 bool is_bound() const { return handle_.is_valid() || router_; }
110
111 bool encountered_error() const {
112 return router_ ? router_->encountered_error() : false;
113 }
114
115 void set_connection_error_handler(const Closure& error_handler) {
116 ConfigureProxyIfNecessary();
117
118 MOJO_DCHECK(router_);
119 router_->set_connection_error_handler(error_handler);
120 }
121
122 // Returns true if bound and awaiting a response to a message.
123 bool has_pending_callbacks() const {
124 return router_ && router_->has_pending_responders();
125 }
126
127 Router* router_for_testing() {
128 ConfigureProxyIfNecessary();
129 return router_;
130 }
131
132 private:
133 using Proxy = typename Interface::Proxy_;
134
135 void ConfigureProxyIfNecessary() {
136 // The proxy has been configured.
137 if (proxy_) {
138 MOJO_DCHECK(router_);
139 return;
140 }
141 // The object hasn't been bound.
142 if (!waiter_) {
143 MOJO_DCHECK(!handle_.is_valid());
144 return;
145 }
146
147 FilterChain filters;
148 filters.Append<MessageHeaderValidator>();
149 filters.Append<typename Interface::ResponseValidator_>();
150
151 router_ = new Router(handle_.Pass(), filters.Pass(), waiter_);
152 waiter_ = nullptr;
153
154 proxy_ = new Proxy(router_);
155 }
156
157 Proxy* proxy_;
158 Router* router_;
159
160 // |proxy_| and |router_| are not initialized until read/write with the
161 // message pipe handle is needed. |handle_| and |waiter_| are valid between
162 // the Bind() call and the initialization of |proxy_| and |router_|.
163 ScopedMessagePipeHandle handle_;
164 const MojoAsyncWaiter* waiter_;
165
166 uint32_t version_;
167
168 MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
169 };
170
171 } // namespace internal
172 } // namespace mojo
173
174 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/binding_state.h ('k') | mojo/public/cpp/bindings/lib/interface_ptr_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698