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

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: snapshot 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 T>
20 class InterfacePtr {
21 MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(InterfacePtr, RValue)
22 public:
23 typedef T Interface;
24
25 InterfacePtr() {}
26 explicit InterfacePtr(Interface* impl) { state_.impl = impl; }
27
28 InterfacePtr(RValue other) { other.object->state_.Swap(&state_); }
29 InterfacePtr& operator=(RValue other) {
30 other.object->state_.Swap(&state_);
31 return *this;
32 }
33
34 ~InterfacePtr() {}
35
36 Interface* get() const {
37 return state_.impl;
38 }
39 Interface* operator->() const { return get(); }
40 Interface* operator*() const { return get(); }
41
42 void reset() {
43 State doomed;
44 state_.Swap(&doomed);
45 }
46
47 void Bind(Interface* impl) {
48 reset();
49 state_.impl = impl;
50 }
51
52 bool encountered_error() const;
53
54 void set_error_handler(ErrorHandler* error_handler);
55
56 // XXX figure out how to hide these!
57
58 bool has_context() const { return !!state_.context; }
59
60 void ConfigureProxy(ScopedMessagePipeHandle handle,
61 MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
62 assert(!state_.impl);
63 assert(!state_.context);
64
65 internal::InterfacePtrContext* context =
66 new internal::InterfacePtrContext(handle.Pass(), waiter);
67 ProxyWithStub* proxy = new ProxyWithStub(context->router());
68 context->router()->set_incoming_receiver(&proxy->stub);
69
70 state_.impl = proxy;
71 state_.context = context;
72 }
73
74 void ConfigureStub(ScopedMessagePipeHandle handle,
75 MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
76 assert(state_.impl); // Should have already been set!
77 assert(!state_.context);
78
79 // Stub for binding to state_.impl
80 // Proxy for communicating to the client on the other end of the pipe.
81
82 internal::InterfacePtrContext* context =
83 new internal::InterfacePtrContext(handle.Pass(), waiter);
84 ClientProxyWithStub* proxy = new ClientProxyWithStub(context->router());
85 proxy->stub.set_sink(state_.impl);
86 context->router()->set_incoming_receiver(&proxy->stub);
87
88 state_.impl->SetClient(proxy);
89
90 state_.client = proxy;
91 state_.context = context;
92 }
93
94 void Detach() {
95 new DetachedState(&state_);
96 }
97
98 private:
99 struct ProxyWithStub : public Interface::Proxy_ {
100 explicit ProxyWithStub(MessageReceiver* receiver)
101 : Interface::Proxy_(receiver) {
102 }
103 virtual void SetClient(typename Interface::Client_* client) MOJO_OVERRIDE {
104 stub.set_sink(client);
105 }
106 typename Interface::Client_::Stub_ stub;
107 };
108
109 struct ClientProxyWithStub : public Interface::Client_::Proxy_ {
110 explicit ClientProxyWithStub(MessageReceiver* receiver)
111 : Interface::Client_::Proxy_(receiver) {
112 }
113 typename Interface::Stub_ stub;
114 };
115
116 struct State {
117 State() : impl(NULL), client(NULL), context(NULL) {}
118
119 ~State() {
120 delete context; // context depends on impl
121 delete impl; // impl depends on client
122 delete client;
123 }
124
125 void Swap(State* other) {
126 std::swap(other->impl, impl);
127 std::swap(other->client, client);
128 std::swap(other->context, context);
129 }
130
131 Interface* impl;
132 typename Interface::Client_* client;
133 internal::InterfacePtrContext* context;
134
135 MOJO_DISALLOW_COPY_AND_ASSIGN(State);
136 };
137
138 class DetachedState : public ErrorHandler {
139 public:
140 explicit DetachedState(State* state) {
141 internal::LogDetachedState(this, +1);
142
143 state_.Swap(state);
144
145 assert(state_.context);
146 assert(!state_.context->router()->encountered_error());
147
148 // Register to observe when the pipe is broken.
149 state_.context->router()->set_error_handler(this);
150 }
151
152 virtual void OnError() MOJO_OVERRIDE {
153 internal::LogDetachedState(this, -1);
154
155 delete this;
156 }
157
158 State state_;
159 };
160
161 State state_;
162 };
163
164 // Takes a handle to the proxy end-point of a pipe. On the other end is
165 // presumed to be an interface implementation of type |Interface|. Returns a
166 // generated proxy to that interface, which may be used on the current thread.
167 // It is valid to call SetClient on the returned Interface to set an instance
168 // of Interface::Client.
169 //
170 // XXX not sure if MakeProxy is the best name here.
171 template <typename Interface>
172 InterfacePtr<Interface> MakeProxy(
173 ScopedMessagePipeHandle handle,
174 MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()) {
175 InterfacePtr<Interface> ptr;
176 if (handle.is_valid())
177 ptr.ConfigureProxy(handle.Pass(), waiter);
178 return ptr.Pass();
179 }
180
181 // Takes a heap-allocated interface implementation and binds its lifetime to
182 // that of a MessagePipe. A handle to the proxy end-point of the pipe is
183 // returned. If that pipe is closed, then the interface implementation will be
184 // deleted.
185 //
186 // The interface implementation is also bound to the current thread. Its
187 // methods will only be called on the current thread, and if the current thread
188 // exits, then it will also be deleted and its end point of the pipe will be
189 // closed.
190 //
191 // Before returning the interface implementation will receive a SetClient call,
192 // providing it with a proxy to the client on the other end of the pipe.
193 //
194 // XXX not sure if BindToPipe is the best name here.
195 template <typename Interface>
196 ScopedMessagePipeHandle BindToPipe(Interface* impl) {
197 InterfacePtr<Interface> ptr(impl);
198 MessagePipe pipe;
199 ptr.ConfigureStub(pipe.handle0.Pass());
200 ptr.Detach();
201 return pipe.handle1.Pass();
202 }
203
204 } // namespace mojo
205
206 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698