OLD | NEW |
| (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_REQUEST_H_ | |
6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_ | |
7 | |
8 #include <cstddef> | |
9 #include <utility> | |
10 | |
11 #include "mojo/public/cpp/system/message_pipe.h" | |
12 | |
13 namespace mojo { | |
14 | |
15 template <typename I> | |
16 class InterfacePtr; | |
17 | |
18 template <typename I> | |
19 class InterfaceHandle; | |
20 | |
21 // Represents a request from a remote client for an implementation of Interface | |
22 // over a specified message pipe. The implementor of the interface should | |
23 // remove the message pipe by calling PassMessagePipe() and bind it to the | |
24 // implementation. If this is not done, the InterfaceRequest will automatically | |
25 // close the pipe on destruction. Can also represent the absence of a request | |
26 // if the client did not provide a message pipe. | |
27 template <typename Interface> | |
28 class InterfaceRequest { | |
29 public: | |
30 // Constructs an "empty" InterfaceRequest, representing that the client is not | |
31 // requesting an implementation of Interface. | |
32 InterfaceRequest() {} | |
33 InterfaceRequest(std::nullptr_t) {} | |
34 | |
35 // Constructs an InterfaceRequest from a message pipe handle (if |handle| is | |
36 // not set, then this constructs an "empty" InterfaceRequest). | |
37 explicit InterfaceRequest(ScopedMessagePipeHandle handle) | |
38 : handle_(handle.Pass()) {} | |
39 | |
40 // Takes the message pipe from another InterfaceRequest. | |
41 InterfaceRequest(InterfaceRequest&& other) { handle_ = other.handle_.Pass(); } | |
42 InterfaceRequest& operator=(InterfaceRequest&& other) { | |
43 handle_ = other.handle_.Pass(); | |
44 return *this; | |
45 } | |
46 | |
47 // Assigning to nullptr resets the InterfaceRequest to an empty state, | |
48 // closing the message pipe currently bound to it (if any). | |
49 InterfaceRequest& operator=(std::nullptr_t) { | |
50 handle_.reset(); | |
51 return *this; | |
52 } | |
53 | |
54 // Binds the request to a message pipe over which Interface is to be | |
55 // requested. If the request is already bound to a message pipe, the current | |
56 // message pipe will be closed. | |
57 void Bind(ScopedMessagePipeHandle handle) { handle_ = handle.Pass(); } | |
58 | |
59 // Indicates whether the request currently contains a valid message pipe. | |
60 bool is_pending() const { return handle_.is_valid(); } | |
61 | |
62 // Removes the message pipe from the request and returns it. | |
63 ScopedMessagePipeHandle PassMessagePipe() { return handle_.Pass(); } | |
64 | |
65 private: | |
66 ScopedMessagePipeHandle handle_; | |
67 | |
68 MOJO_MOVE_ONLY_TYPE(InterfaceRequest); | |
69 }; | |
70 | |
71 // Creates a new message pipe over which Interface is to be served, and one end | |
72 // into the supplied |handle| and the returns the other inside an | |
73 // InterfaceRequest<>. The InterfaceHandle<> can be used to create a client | |
74 // proxy (such as an InterfacePtr<> or SynchronousInterfacePtr<>). | |
75 // InterfaceRequest<> should be passed to whatever will provide the | |
76 // implementation. | |
77 // TODO(vardhan): Rename this function? This isn't making a "proxy" you can use, | |
78 // as you still need to convert it into something like InterfacePtr<>. | |
79 template <typename Interface> | |
80 InterfaceRequest<Interface> GetProxy(InterfaceHandle<Interface>* handle) { | |
81 MessagePipe pipe; | |
82 *handle = InterfaceHandle<Interface>(pipe.handle0.Pass(), 0u); | |
83 return InterfaceRequest<Interface>(pipe.handle1.Pass()); | |
84 } | |
85 | |
86 // Creates a new message pipe over which Interface is to be served. Binds the | |
87 // specified InterfacePtr to one end of the message pipe, and returns an | |
88 // InterfaceRequest bound to the other. The InterfacePtr should be passed to | |
89 // the client, and the InterfaceRequest should be passed to whatever will | |
90 // provide the implementation. The implementation should typically be bound to | |
91 // the InterfaceRequest using the Binding or StrongBinding classes. The client | |
92 // may begin to issue calls even before an implementation has been bound, since | |
93 // messages sent over the pipe will just queue up until they are consumed by | |
94 // the implementation. | |
95 // | |
96 // Example #1: Requesting a remote implementation of an interface. | |
97 // =============================================================== | |
98 // | |
99 // Given the following interface: | |
100 // | |
101 // interface Database { | |
102 // OpenTable(Table& table); | |
103 // } | |
104 // | |
105 // The client would have code similar to the following: | |
106 // | |
107 // DatabasePtr database = ...; // Connect to database. | |
108 // TablePtr table; | |
109 // database->OpenTable(GetProxy(&table)); | |
110 // | |
111 // Upon return from GetProxy, |table| is ready to have methods called on it. | |
112 // | |
113 // Example #2: Registering a local implementation with a remote service. | |
114 // ===================================================================== | |
115 // | |
116 // Given the following interface | |
117 // interface Collector { | |
118 // RegisterSource(Source source); | |
119 // } | |
120 // | |
121 // The client would have code similar to the following: | |
122 // | |
123 // CollectorPtr collector = ...; // Connect to Collector. | |
124 // SourcePtr source; | |
125 // InterfaceRequest<Source> source_request = GetProxy(&source); | |
126 // collector->RegisterSource(source.Pass()); | |
127 // CreateSource(source_request.Pass()); // Create implementation locally. | |
128 // | |
129 // TODO(vardhan): Move this function into interface_ptr.h | |
130 template <typename Interface> | |
131 InterfaceRequest<Interface> GetProxy(InterfacePtr<Interface>* ptr) { | |
132 InterfaceHandle<Interface> iface_handle; | |
133 auto retval = GetProxy(&iface_handle); | |
134 *ptr = InterfacePtr<Interface>::Create(std::move(iface_handle)); | |
135 return retval; | |
136 } | |
137 | |
138 } // namespace mojo | |
139 | |
140 #endif // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_ | |
OLD | NEW |