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

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

Issue 400043004: InterfacePtr: not configure proxy until actual read/write is needed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
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_INTERNAL_H_ 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
7 7
8 #include <assert.h> 8 #include <assert.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 10
11 #include "mojo/public/cpp/bindings/lib/filter_chain.h" 11 #include "mojo/public/cpp/bindings/lib/filter_chain.h"
12 #include "mojo/public/cpp/bindings/lib/message_header_validator.h" 12 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
13 #include "mojo/public/cpp/bindings/lib/router.h" 13 #include "mojo/public/cpp/bindings/lib/router.h"
14 #include "mojo/public/cpp/environment/environment.h" 14
15 struct MojoAsyncWaiter;
15 16
16 namespace mojo { 17 namespace mojo {
17 namespace internal { 18 namespace internal {
18 19
19 template <typename Interface> 20 template <typename Interface>
20 class InterfacePtrState { 21 class InterfacePtrState {
21 public: 22 public:
22 InterfacePtrState() : proxy_(NULL), router_(NULL) {} 23 InterfacePtrState() : proxy_(NULL), router_(NULL), waiter_(NULL) {}
23 24
24 ~InterfacePtrState() { 25 ~InterfacePtrState() {
25 // Destruction order matters here. We delete |proxy_| first, even though 26 // Destruction order matters here. We delete |proxy_| first, even though
26 // |router_| may have a reference to it, so that |~Interface| may have a 27 // |router_| may have a reference to it, so that |~Interface| may have a
27 // shot at generating new outbound messages (ie, invoking client methods). 28 // shot at generating new outbound messages (ie, invoking client methods).
28 delete proxy_; 29 delete proxy_;
29 delete router_; 30 delete router_;
30 } 31 }
31 32
32 Interface* instance() const { return proxy_; } 33 Interface* instance() {
34 ConfigureProxyIfNecessary();
33 35
34 Router* router() const { return router_; } 36 // This will be NULL if the object is not bound.
37 return proxy_;
38 }
35 39
36 void Swap(InterfacePtrState* other) { 40 void Swap(InterfacePtrState* other) {
37 std::swap(other->proxy_, proxy_); 41 std::swap(other->proxy_, proxy_);
38 std::swap(other->router_, router_); 42 std::swap(other->router_, router_);
43 handle_.swap(other->handle_);
44 std::swap(other->waiter_, waiter_);
39 } 45 }
40 46
41 void ConfigureProxy( 47 void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
42 ScopedMessagePipeHandle handle,
43 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
44 assert(!proxy_); 48 assert(!proxy_);
45 assert(!router_); 49 assert(!router_);
50 assert(!handle_.is_valid());
51 assert(!waiter_);
46 52
47 FilterChain filters; 53 handle_ = handle.Pass();
48 filters.Append<MessageHeaderValidator>(); 54 waiter_ = waiter;
49 filters.Append<typename Interface::Client::RequestValidator_>();
50 filters.Append<typename Interface::ResponseValidator_>();
51
52 router_ = new Router(handle.Pass(), filters.Pass(), waiter);
53 ProxyWithStub* proxy = new ProxyWithStub(router_);
54 router_->set_incoming_receiver(&proxy->stub);
55
56 proxy_ = proxy;
57 } 55 }
58 56
59 bool WaitForIncomingMethodCall() { 57 bool WaitForIncomingMethodCall() {
58 ConfigureProxyIfNecessary();
59
60 assert(router_); 60 assert(router_);
61 return router_->WaitForIncomingMessage(); 61 return router_->WaitForIncomingMessage();
62 } 62 }
63 63
64 ScopedMessagePipeHandle PassMessagePipe() {
65 if (router_)
66 return router_->PassMessagePipe();
67
68 waiter_ = NULL;
69 return handle_.Pass();
70 }
71
64 void set_client(typename Interface::Client* client) { 72 void set_client(typename Interface::Client* client) {
73 ConfigureProxyIfNecessary();
74
65 assert(proxy_); 75 assert(proxy_);
66 proxy_->stub.set_sink(client); 76 proxy_->stub.set_sink(client);
67 } 77 }
68 78
79 bool encountered_error() const {
80 return router_ ? router_->encountered_error() : false;
81 }
82
83 void set_error_handler(ErrorHandler* error_handler) {
84 ConfigureProxyIfNecessary();
85
86 assert(router_);
87 router_->set_error_handler(error_handler);
88 }
89
90 Router* router_for_testing() {
91 ConfigureProxyIfNecessary();
92 return router_;
93 }
94
69 private: 95 private:
70 class ProxyWithStub : public Interface::Proxy_ { 96 class ProxyWithStub : public Interface::Proxy_ {
71 public: 97 public:
72 explicit ProxyWithStub(MessageReceiverWithResponder* receiver) 98 explicit ProxyWithStub(MessageReceiverWithResponder* receiver)
73 : Interface::Proxy_(receiver) { 99 : Interface::Proxy_(receiver) {
74 } 100 }
75 typename Interface::Client::Stub_ stub; 101 typename Interface::Client::Stub_ stub;
76 private: 102 private:
77 MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub); 103 MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
78 }; 104 };
79 105
106 void ConfigureProxyIfNecessary() {
107 // The proxy has been configured.
108 if (proxy_) {
109 assert(router_);
110 return;
111 }
112 // The object hasn't been bound.
113 if (!waiter_) {
114 assert(!handle_.is_valid());
115 return;
116 }
117
118 FilterChain filters;
119 filters.Append<MessageHeaderValidator>();
120 filters.Append<typename Interface::Client::RequestValidator_>();
121 filters.Append<typename Interface::ResponseValidator_>();
122
123 router_ = new Router(handle_.Pass(), filters.Pass(), waiter_);
124 waiter_ = NULL;
125
126 ProxyWithStub* proxy = new ProxyWithStub(router_);
127 router_->set_incoming_receiver(&proxy->stub);
128
129 proxy_ = proxy;
130 }
131
80 ProxyWithStub* proxy_; 132 ProxyWithStub* proxy_;
81 Router* router_; 133 Router* router_;
82 134
135 // |proxy_| and |router_| are not initialized until read/write with the
136 // message pipe handle is needed. Before that, |handle_| and |waiter_| store
137 // the arguments of Bind().
138 ScopedMessagePipeHandle handle_;
139 const MojoAsyncWaiter* waiter_;
140
83 MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState); 141 MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
84 }; 142 };
85 143
86 } // namespace internal 144 } // namespace internal
87 } // namespace mojo 145 } // namespace mojo
88 146
89 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_ 147 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/interface_ptr.h ('k') | mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698