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

Side by Side Diff: mojo/public/cpp/bindings/interface_ptr.h

Issue 265793015: Mojo: Replace RemotePtr with InterfacePtr and InterfaceImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 7 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
(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_INTERFACE_PTR_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
7
8 #include <assert.h>
9 #include <stdio.h>
10
11 #include <algorithm>
12
13 #include "mojo/public/cpp/bindings/error_handler.h"
14 #include "mojo/public/cpp/bindings/lib/interface_ptr_internal.h"
15 #include "mojo/public/cpp/system/macros.h"
16
17 namespace mojo {
18
19 template <typename Interface>
20 class InterfacePtr {
21 MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr, RValue)
22 public:
23 InterfacePtr() {}
24 explicit InterfacePtr(Interface* impl) { state_.impl = impl; }
25
26 InterfacePtr(RValue other) { other.object->state_.Swap(&state_); }
27 InterfacePtr& operator=(RValue other) {
28 other.object->state_.Swap(&state_);
29 return *this;
30 }
31
32 ~InterfacePtr() {}
33
34 Interface* get() const {
35 return state_.impl;
36 }
37 Interface* operator->() const { return get(); }
38 Interface* operator*() const { return get(); }
39
40 void reset() {
41 State doomed;
42 state_.Swap(&doomed);
43 }
44
45 void Bind(Interface* impl) {
46 reset();
47 state_.impl = impl;
48 }
49
50 bool encountered_error() const;
51
52 void set_error_handler(ErrorHandler* error_handler) {
53 assert(state_.context);
54 state_.context->router()->set_error_handler(error_handler);
55 }
56
57 // XXX figure out how to hide these!
58
59 bool has_context() const { return !!state_.context; }
60
61 void ConfigureProxy(ScopedMessagePipeHandle handle,
62 MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
63 assert(!state_.impl);
64 assert(!state_.context);
65
66 internal::InterfacePtrContext* context =
67 new internal::InterfacePtrContext(handle.Pass(), waiter);
68 ProxyWithStub* proxy = new ProxyWithStub(context->router());
69 context->router()->set_incoming_receiver(&proxy->stub);
70
71 state_.impl = proxy;
72 state_.context = context;
73 }
74
75 void ConfigureStub(ScopedMessagePipeHandle handle,
76 MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
77 assert(state_.impl); // Should have already been set!
78 assert(!state_.context);
79
80 // Stub for binding to state_.impl
81 // Proxy for communicating to the client on the other end of the pipe.
82
83 internal::InterfacePtrContext* context =
84 new internal::InterfacePtrContext(handle.Pass(), waiter);
85 ClientProxyWithStub* proxy = new ClientProxyWithStub(context->router());
86 proxy->stub.set_sink(state_.impl);
87 context->router()->set_incoming_receiver(&proxy->stub);
88
89 state_.impl->SetClient(proxy);
90
91 state_.client = proxy;
92 state_.context = context;
93 }
94
95 void Detach() {
96 new DetachedState(&state_);
97 }
98
99 internal::Router* router_for_testing() { return state_.context->router(); }
100
101 private:
102 class ProxyWithStub : public Interface::Proxy_ {
103 public:
104 explicit ProxyWithStub(MessageReceiver* receiver)
105 : Interface::Proxy_(receiver) {
106 }
107 virtual void SetClient(typename Interface::Client_* client) MOJO_OVERRIDE {
108 stub.set_sink(client);
109 }
110 typename Interface::Client_::Stub_ stub;
111 private:
112 MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
113 };
114
115 class ClientProxyWithStub : public Interface::Client_::Proxy_ {
116 public:
117 explicit ClientProxyWithStub(MessageReceiver* receiver)
118 : Interface::Client_::Proxy_(receiver) {
119 }
120 typename Interface::Stub_ stub;
121 private:
122 MOJO_DISALLOW_COPY_AND_ASSIGN(ClientProxyWithStub);
123 };
124
125 struct State {
126 State() : impl(NULL), client(NULL), context(NULL) {}
127
128 ~State() {
129 // Destruction order matters here. We delete |impl| first, even though
130 // |context| may have a reference to it, so that |~Interface| may have a
131 // shot at generating new outbound messages (ie, nvoking client methods).
132 delete impl;
133 delete context;
134 delete client;
135 }
136
137 void Swap(State* other) {
138 std::swap(other->impl, impl);
139 std::swap(other->client, client);
140 std::swap(other->context, context);
141 }
142
143 Interface* impl;
144 typename Interface::Client_* client;
145 internal::InterfacePtrContext* context;
146
147 MOJO_DISALLOW_COPY_AND_ASSIGN(State);
148 };
149
150 class DetachedState : public ErrorHandler {
151 public:
152 explicit DetachedState(State* state) {
153 internal::LogDetachedState(this, +1);
154
155 state_.Swap(state);
156
157 assert(state_.context);
158 assert(!state_.context->router()->encountered_error());
159
160 // Register to observe when the pipe is broken.
161 state_.context->router()->set_error_handler(this);
162 }
163
164 virtual void OnError() MOJO_OVERRIDE {
165 internal::LogDetachedState(this, -1);
166
167 delete this;
168 }
169
170 private:
171 State state_;
172
173 MOJO_DISALLOW_COPY_AND_ASSIGN(DetachedState);
174 };
175
176 State state_;
177 };
178
179 // Takes a handle to the proxy end-point of a pipe. On the other end is
180 // presumed to be an interface implementation of type |Interface|. Returns a
181 // generated proxy to that interface, which may be used on the current thread.
182 // It is valid to call SetClient on the returned Interface to set an instance
183 // of Interface::Client.
184 //
DaveMoore 2014/05/06 21:30:54 Maybe there should be a variant of this that takes
darin (slow to review) 2014/05/06 21:39:11 Yeah, that's something I've been considering as we
185 // XXX not sure if MakeProxy is the best name here.
186 template <typename Interface>
187 InterfacePtr<Interface> MakeProxy(
188 ScopedMessagePipeHandle handle,
189 MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
190 InterfacePtr<Interface> ptr;
191 if (handle.is_valid())
192 ptr.ConfigureProxy(handle.Pass(), waiter);
193 return ptr.Pass();
194 }
195
196 // Takes a heap-allocated interface implementation and binds its lifetime to
197 // that of a MessagePipe. A handle to the proxy end-point of the pipe is
198 // returned. If that pipe is closed, then the interface implementation will be
199 // deleted.
200 //
201 // The interface implementation is also bound to the current thread. Its
202 // methods will only be called on the current thread, and if the current thread
203 // exits, then it will also be deleted and its end point of the pipe will be
204 // closed.
205 //
206 // Before returning the interface implementation will receive a SetClient call,
207 // providing it with a proxy to the client on the other end of the pipe.
208 //
209 // XXX not sure if BindToPipe is the best name here.
210 template <typename Interface>
211 ScopedMessagePipeHandle BindToPipe(Interface* impl) {
212 InterfacePtr<Interface> ptr(impl);
213 MessagePipe pipe;
214 ptr.ConfigureStub(pipe.handle0.Pass());
215 ptr.Detach();
216 return pipe.handle1.Pass();
217 }
218
219 } // namespace mojo
220
221 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698