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

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

Issue 2205193002: WIP: Reduce code size of InterfacePtrState (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@before-sharing
Patch Set: Add missing, new .cc file Created 4 years, 4 months 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_
7 7
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> // For |std::swap()|. 10 #include <algorithm> // For |std::swap()|.
(...skipping 17 matching lines...) Expand all
28 #include "mojo/public/cpp/bindings/lib/router.h" 28 #include "mojo/public/cpp/bindings/lib/router.h"
29 #include "mojo/public/cpp/bindings/message_header_validator.h" 29 #include "mojo/public/cpp/bindings/message_header_validator.h"
30 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 30 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
31 31
32 namespace mojo { 32 namespace mojo {
33 namespace internal { 33 namespace internal {
34 34
35 template <typename Interface, bool use_multiplex_router> 35 template <typename Interface, bool use_multiplex_router>
36 class InterfacePtrState; 36 class InterfacePtrState;
37 37
38 // Non-templated base class to reduce the amount of code generated for every
39 // mojom file.
40 class SimpleInterfacePtrState {
41 public:
42 SimpleInterfacePtrState();
43
44 ~SimpleInterfacePtrState();
45
46 uint32_t version() const { return version_; }
47
48 void QueryVersion(const base::Callback<void(uint32_t)>& callback);
49
50 void RequireVersion(uint32_t version);
51
52 bool HasAssociatedInterfaces() const;
53
54 bool is_bound() const { return handle_.is_valid() || router_; }
55
56 bool encountered_error() const {
57 return router_ ? router_->encountered_error() : false;
58 }
59
60 void set_connection_error_handler(const base::Closure& error_handler) {
61 ConfigureProxyIfNecessary();
62
63 DCHECK(router_);
64 router_->set_connection_error_handler(error_handler);
65 }
66
67 // Returns true if bound and awaiting a response to a message.
68 bool has_pending_callbacks() const {
69 return router_ && router_->has_pending_responders();
70 }
71
72 AssociatedGroup* associated_group() { return nullptr; }
73
74 void EnableTestingMode();
75
76 protected:
77 void BindInternal(InterfacePtrInfoBase* info,
78 scoped_refptr<base::SingleThreadTaskRunner> runner);
79
80 virtual void ConfigureProxyIfNecessary() = 0;
81
82 bool ConfigureProxyIfNecessaryInternal(const char* interface_name);
83
84 virtual MessageFilter* CreateRequestValidator() = 0;
85
86 virtual ControlMessageProxy* proxy() = 0;
87
88 Router* router_;
89
90 // |proxy_| and |router_| are not initialized until read/write with the
91 // message pipe handle is needed. |handle_| is valid between the Bind() call
92 // and the initialization of |proxy_| and |router_|.
93 ScopedMessagePipeHandle handle_;
94 scoped_refptr<base::SingleThreadTaskRunner> runner_;
95
96 uint32_t version_;
97
98 private:
99 void OnQueryVersion(const base::Callback<void(uint32_t)>& callback,
100 uint32_t version);
101 };
102
38 // Uses a single-threaded, dedicated router. If |Interface| doesn't have any 103 // Uses a single-threaded, dedicated router. If |Interface| doesn't have any
39 // methods to pass associated interface pointers or requests, there won't be 104 // methods to pass associated interface pointers or requests, there won't be
40 // multiple interfaces running on the underlying message pipe. In that case, we 105 // multiple interfaces running on the underlying message pipe. In that case, we
41 // can use this specialization to reduce cost. 106 // can use this specialization to reduce cost.
42 template <typename Interface> 107 template <typename Interface>
43 class InterfacePtrState<Interface, false> { 108 class InterfacePtrState<Interface, false> : public SimpleInterfacePtrState {
44 public: 109 public:
45 InterfacePtrState() : proxy_(nullptr), router_(nullptr), version_(0u) {} 110 InterfacePtrState() : proxy_(nullptr) {}
46 111
47 ~InterfacePtrState() { 112 ~InterfacePtrState() {
48 // Destruction order matters here. We delete |proxy_| first, even though 113 // Destruction order matters here. We delete |proxy_| first, even though
49 // |router_| may have a reference to it, so that destructors for any request 114 // |router_| may have a reference to it, so that destructors for any request
50 // callbacks still pending can interact with the InterfacePtr. 115 // callbacks still pending can interact with the InterfacePtr.
51 delete proxy_; 116 delete proxy_;
52 delete router_;
53 } 117 }
54 118
55 Interface* instance() { 119 Interface* instance() {
56 ConfigureProxyIfNecessary(); 120 ConfigureProxyIfNecessary();
57 121
58 // This will be null if the object is not bound. 122 // This will be null if the object is not bound.
59 return proxy_; 123 return proxy_;
60 } 124 }
61 125
62 uint32_t version() const { return version_; }
63
64 void QueryVersion(const base::Callback<void(uint32_t)>& callback) {
65 ConfigureProxyIfNecessary();
66
67 // Do a static cast in case the interface contains methods with the same
68 // name. It is safe to capture |this| because the callback won't be run
69 // after this object goes away.
70 static_cast<ControlMessageProxy*>(proxy_)->QueryVersion(
71 base::Bind(&InterfacePtrState::OnQueryVersion, base::Unretained(this),
72 callback));
73 }
74
75 void RequireVersion(uint32_t version) {
76 ConfigureProxyIfNecessary();
77
78 if (version <= version_)
79 return;
80
81 version_ = version;
82 // Do a static cast in case the interface contains methods with the same
83 // name.
84 static_cast<ControlMessageProxy*>(proxy_)->RequireVersion(version);
85 }
86
87 void Swap(InterfacePtrState* other) { 126 void Swap(InterfacePtrState* other) {
88 using std::swap; 127 using std::swap;
89 swap(other->proxy_, proxy_); 128 swap(other->proxy_, proxy_);
90 swap(other->router_, router_); 129 swap(other->router_, router_);
91 handle_.swap(other->handle_); 130 handle_.swap(other->handle_);
92 runner_.swap(other->runner_); 131 runner_.swap(other->runner_);
93 swap(other->version_, version_); 132 swap(other->version_, version_);
94 } 133 }
95 134
96 void Bind(InterfacePtrInfo<Interface> info, 135 void Bind(InterfacePtrInfo<Interface> info,
97 scoped_refptr<base::SingleThreadTaskRunner> runner) { 136 scoped_refptr<base::SingleThreadTaskRunner> runner) {
98 DCHECK(!proxy_); 137 DCHECK(!proxy_);
99 DCHECK(!router_); 138 BindInternal(&info, runner);
100 DCHECK(!handle_.is_valid());
101 DCHECK_EQ(0u, version_);
102 DCHECK(info.is_valid());
103
104 handle_ = info.PassHandle();
105 version_ = info.version();
106 runner_ = std::move(runner);
107 } 139 }
108 140
109 bool HasAssociatedInterfaces() const { return false; }
110
111 // After this method is called, the object is in an invalid state and 141 // After this method is called, the object is in an invalid state and
112 // shouldn't be reused. 142 // shouldn't be reused.
113 InterfacePtrInfo<Interface> PassInterface() { 143 InterfacePtrInfo<Interface> PassInterface() {
114 return InterfacePtrInfo<Interface>( 144 return InterfacePtrInfo<Interface>(
115 router_ ? router_->PassMessagePipe() : std::move(handle_), version_); 145 router_ ? router_->PassMessagePipe() : std::move(handle_), version_);
116 } 146 }
117 147
118 bool is_bound() const { return handle_.is_valid() || router_; }
119
120 bool encountered_error() const {
121 return router_ ? router_->encountered_error() : false;
122 }
123
124 void set_connection_error_handler(const base::Closure& error_handler) {
125 ConfigureProxyIfNecessary();
126
127 DCHECK(router_);
128 router_->set_connection_error_handler(error_handler);
129 }
130
131 // Returns true if bound and awaiting a response to a message.
132 bool has_pending_callbacks() const {
133 return router_ && router_->has_pending_responders();
134 }
135
136 AssociatedGroup* associated_group() { return nullptr; }
137
138 void EnableTestingMode() {
139 ConfigureProxyIfNecessary();
140 router_->EnableTestingMode();
141 }
142
143 private: 148 private:
144 using Proxy = typename Interface::Proxy_; 149 using Proxy = typename Interface::Proxy_;
145 150
146 void ConfigureProxyIfNecessary() { 151 void ConfigureProxyIfNecessary() override {
147 // The proxy has been configured. 152 // The proxy has been configured.
148 if (proxy_) { 153 if (proxy_) {
149 DCHECK(router_); 154 DCHECK(router_);
150 return; 155 return;
151 } 156 }
152 // The object hasn't been bound. 157 if (!SimpleInterfacePtrState::ConfigureProxyIfNecessaryInternal(
153 if (!handle_.is_valid()) 158 Interface::Name_)) {
154 return; 159 return;
155 160 }
156 FilterChain filters;
157 filters.Append<MessageHeaderValidator>(Interface::Name_);
158 filters.Append<typename Interface::ResponseValidator_>();
159
160 router_ = new Router(std::move(handle_), std::move(filters), false,
161 std::move(runner_));
162
163 proxy_ = new Proxy(router_); 161 proxy_ = new Proxy(router_);
164 } 162 }
165 163
166 void OnQueryVersion(const base::Callback<void(uint32_t)>& callback, 164 MessageFilter* CreateRequestValidator() override {
167 uint32_t version) { 165 return new typename Interface::ResponseValidator_();
168 version_ = version;
169 callback.Run(version);
170 } 166 }
171 167
168 ControlMessageProxy* proxy() override { return proxy_; }
169
172 Proxy* proxy_; 170 Proxy* proxy_;
173 Router* router_;
174
175 // |proxy_| and |router_| are not initialized until read/write with the
176 // message pipe handle is needed. |handle_| is valid between the Bind() call
177 // and the initialization of |proxy_| and |router_|.
178 ScopedMessagePipeHandle handle_;
179 scoped_refptr<base::SingleThreadTaskRunner> runner_;
180
181 uint32_t version_;
182 171
183 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); 172 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
184 }; 173 };
185 174
186 // Uses a multiplexing router. If |Interface| has methods to pass associated 175 // Uses a multiplexing router. If |Interface| has methods to pass associated
187 // interface pointers or requests, this specialization should be used. 176 // interface pointers or requests, this specialization should be used.
188 template <typename Interface> 177 template <typename Interface>
189 class InterfacePtrState<Interface, true> { 178 class InterfacePtrState<Interface, true> {
190 public: 179 public:
191 InterfacePtrState() : version_(0u) {} 180 InterfacePtrState() : version_(0u) {}
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 328
340 uint32_t version_; 329 uint32_t version_;
341 330
342 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); 331 DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
343 }; 332 };
344 333
345 } // namespace internal 334 } // namespace internal
346 } // namespace mojo 335 } // namespace mojo
347 336
348 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_ 337 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_STATE_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/interface_ptr_info.cc ('k') | mojo/public/cpp/bindings/lib/interface_ptr_state.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698