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

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

Issue 1455063004: Mojo C++ bindings: introduce MultiplexRouter and related classes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 1 month 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
(Empty)
1 // Copyright 2015 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_LIB_MULTIPLEX_ROUTER_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_
7
8 #include <deque>
9 #include <map>
10
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/ref_counted_delete_on_message_loop.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/synchronization/lock.h"
18 #include "base/threading/thread_checker.h"
19 #include "mojo/public/cpp/bindings/callback.h"
20 #include "mojo/public/cpp/bindings/lib/connector.h"
21 #include "mojo/public/cpp/bindings/lib/interface_id.h"
22 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
23 #include "mojo/public/cpp/bindings/lib/pipe_control_message_handler.h"
24 #include "mojo/public/cpp/bindings/lib/pipe_control_message_handler_delegate.h"
25 #include "mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h"
26 #include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
27 #include "mojo/public/cpp/environment/environment.h"
28
29 namespace mojo {
30 namespace internal {
31
32 class InterfaceEndpointClient;
33
34 // MultiplexRouter supports routing messages for multiple interfaces over a
35 // single message pipe.
36 //
37 // It is created on the thread where the master interface of the message pipe
38 // lives. Although it is ref-counted, it is guarateed to be destructed on the
39 // same thread.
40 // Some public methods are only allowed to be called on the creating thread;
41 // while the others are safe to call from any threads. Please see the method
42 // comments for more details.
43 class MultiplexRouter
44 : public MessageReceiver,
45 public base::RefCountedDeleteOnMessageLoop<MultiplexRouter>,
46 public PipeControlMessageHandlerDelegate {
47 public:
48 // If |set_interface_id_namespace_bit| is true, the interface IDs generated by
49 // this router will have the highest bit set.
50 MultiplexRouter(
51 bool set_interface_id_namespace_bit,
52 ScopedMessagePipeHandle message_pipe,
53 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter());
54
55 // ---------------------------------------------------------------------------
56 // The following public methods are safe to call from any threads.
57
58 // Creates a pair of interface endpoint handles. The method generates a new
59 // interface ID and assigns it to the two handles. |local_endpoint| is used
60 // locally; while |remote_endpoint| is sent over the message pipe.
61 void CreateEndpointHandlePair(ScopedInterfaceEndpointHandle* local_endpoint,
62 ScopedInterfaceEndpointHandle* remote_endpoint);
63
64 // Creates an interface endpoint handle from a given interface ID. The handle
65 // is used locally.
66 // Typically, this method is used to (1) create an endpoint handle for the
67 // master interface; or (2) create an endpoint handle on receiving an
68 // interface ID from the message pipe.
69 ScopedInterfaceEndpointHandle CreateLocalEndpointHandle(InterfaceId id);
70
71 // Closes an interface endpoint handle.
72 void CloseEndpointHandle(InterfaceId id, bool is_local);
73
74 // Attaches an client to the specified endpoint to send and receive messages.
75 void AttachEndpointClient(const ScopedInterfaceEndpointHandle& handle,
76 InterfaceEndpointClient* endpoint_client);
77 // Detaches the client attached to the specified endpoint. It should be called
78 // on the same thread as the corresponding AttachEndpointClient() call.
79 void DetachEndpointClient(const ScopedInterfaceEndpointHandle& handle);
80
81 bool SendMessage(const ScopedInterfaceEndpointHandle& handle,
82 Message* message);
83
84 // Raises an error on the underlying message pipe. It disconnects the pipe
85 // and notifies all interfaces running on this pipe.
86 void RaiseError();
87
88 // ---------------------------------------------------------------------------
89 // The following public methods are called on the creating thread.
90
91 // Please note that this method shouldn't be called unless it results from an
92 // explicit request of the user of bindings (e.g., the user sets an
93 // InterfacePtr to null or closes a Binding).
94 void CloseMessagePipe() {
95 DCHECK(thread_checker_.CalledOnValidThread());
96 connector_.CloseMessagePipe();
97 }
98
99 // Extracts the underlying message pipe.
100 //
101 // TODO(yzshen): For now, users need to make sure there is no one holding on
102 // to associated interface endpoint handles at both sides of the message pipe
103 // in order to call this method. We need a way to forcefully invalidate
104 // associated interface endpoint handles.
105 ScopedMessagePipeHandle PassMessagePipe();
106
107 // Blocks the current thread until the first incoming message, or |deadline|.
108 bool WaitForIncomingMessage(MojoDeadline deadline) {
109 DCHECK(thread_checker_.CalledOnValidThread());
110 return connector_.WaitForIncomingMessage(deadline);
111 }
112
113 // See Binding for details of pause/resume.
114 void PauseIncomingMethodCallProcessing() {
115 DCHECK(thread_checker_.CalledOnValidThread());
116 connector_.PauseIncomingMethodCallProcessing();
117 }
118 void ResumeIncomingMethodCallProcessing() {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 connector_.ResumeIncomingMethodCallProcessing();
121 }
122
123 // Sets this object to testing mode.
124 // In testing mode, the object doesn't disconnect the underlying message pipe
125 // when it receives unexpected or invalid messages.
126 void EnableTestingMode();
127
128 // Is the router bound to a message pipe handle?
129 bool is_valid() const {
130 DCHECK(thread_checker_.CalledOnValidThread());
131 return connector_.is_valid();
132 }
133
134 private:
135 friend class base::RefCountedDeleteOnMessageLoop<MultiplexRouter>;
136 friend class base::DeleteHelper<MultiplexRouter>;
137
138 class InterfaceEndpoint;
139 struct Task;
140
141 ~MultiplexRouter() override;
142
143 // MessageReceiver implementation:
144 bool Accept(Message* message) override;
145
146 // PipeControlMessageHandlerDelegate implementation:
147 bool OnPeerAssociatedEndpointClosed(InterfaceId id) override;
148 bool OnAssociatedEndpointClosedBeforeSent(InterfaceId id) override;
149
150 void OnPipeConnectionError();
151
152 // Processes enqueued tasks (incoming messages and error notifications).
153 // If |force_async| is true, it guarantees not to call any
154 // InterfaceEndpointClient methods directly.
155 //
156 // Note: Because calling into InterfaceEndpointClient may lead to destruction
157 // of this object, if |force_async| is set to false, the caller needs to hold
158 // on to a ref outside of |lock_| before calling this method.
159 void ProcessTasks(bool force_async);
160
161 // Returns true to indicate that |task| has been processed. Otherwise the task
162 // will be added back to the front of the queue.
163 // |*force_async| may be set to true to force subsequent tasks being processed
164 // in an asynchronous manner.
165 bool ProcessNotifyErrorTask(Task* task, bool* force_async);
166 bool ProcessIncomingMessageTask(Task* task, bool* force_async);
167
168 void LockAndCallProcessTasks();
169
170 // Updates the state of |endpoint|. If both the endpoint and its peer have
171 // been closed, removes it from |endpoints_|.
172 // NOTE: The method may invalidate |endpoint|.
173 enum EndpointStateUpdateType { ENDPOINT_CLOSED, PEER_ENDPOINT_CLOSED };
174 void UpdateEndpointStateMayRemove(InterfaceEndpoint* endpoint,
175 EndpointStateUpdateType type);
176
177 void RaiseErrorInNonTestingMode();
178
179 // Whether to set the namespace bit when generating interface IDs. Please see
180 // comments of kInterfaceIdNamespaceMask.
181 const bool set_interface_id_namespace_bit_;
182
183 MessageHeaderValidator header_validator_;
184 Connector connector_;
185 bool encountered_error_;
186
187 base::ThreadChecker thread_checker_;
188
189 // Protects the following members.
190 mutable base::Lock lock_;
191 PipeControlMessageHandler control_message_handler_;
192 PipeControlMessageProxy control_message_proxy_;
193
194 std::map<InterfaceId, scoped_refptr<InterfaceEndpoint>> endpoints_;
195 uint32_t next_interface_id_value_;
196
197 std::deque<scoped_ptr<Task>> tasks_;
198
199 bool testing_mode_;
200
201 DISALLOW_COPY_AND_ASSIGN(MultiplexRouter);
202 };
203
204 } // namespace internal
205 } // namespace mojo
206
207 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/interface_endpoint_client.cc ('k') | mojo/public/cpp/bindings/lib/multiplex_router.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698