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

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: fix mac compilation 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/memory/ref_counted_delete_on_message_loop.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/thread_checker.h"
17 #include "mojo/public/cpp/bindings/callback.h"
18 #include "mojo/public/cpp/bindings/lib/connector.h"
19 #include "mojo/public/cpp/bindings/lib/interface_id.h"
20 #include "mojo/public/cpp/bindings/lib/message_header_validator.h"
21 #include "mojo/public/cpp/bindings/lib/pipe_control_message_handler.h"
22 #include "mojo/public/cpp/bindings/lib/pipe_control_message_handler_delegate.h"
23 #include "mojo/public/cpp/bindings/lib/pipe_control_message_proxy.h"
24 #include "mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.h"
25 #include "mojo/public/cpp/environment/environment.h"
26
27 namespace mojo {
28 namespace internal {
29
30 class InterfaceEndpointClient;
31
32 // MultiplexRouter supports routing messages for multiple interfaces over a
33 // single message pipe.
sky 2015/11/19 17:16:27 Please add a more general description of threading
yzshen1 2015/11/19 22:00:40 Done.
34 class MultiplexRouter
35 : public MessageReceiver,
36 public base::RefCountedDeleteOnMessageLoop<MultiplexRouter>,
37 public PipeControlMessageHandlerDelegate {
38 public:
39 // If |set_interface_id_namespace_bit| is true, the interface IDs generated by
40 // this router will have the highest bit set.
41 MultiplexRouter(
42 bool set_interface_id_namespace_bit,
43 ScopedMessagePipeHandle message_pipe,
44 const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter());
45
46 // ---------------------------------------------------------------------------
47 // The following public methods are safe to call from any threads.
48
49 // Creates a pair of interface endpoint handles. The method generates a new
50 // interface ID and assigns it to the two handles. |local_endpoint| is
51 // supposed to be used locally; while |remote_endpoint| is supposed to be sent
sky 2015/11/19 17:16:27 You can remove 'supposed' to everywhere you have i
yzshen1 2015/11/19 22:00:40 I see. Thanks!
52 // over the message pipe.
53 void CreateEndpointHandlePair(ScopedInterfaceEndpointHandle* local_endpoint,
54 ScopedInterfaceEndpointHandle* remote_endpoint);
55
56 // Creates an interface endpoint handle from a given interface ID. The handle
57 // is supposed to be used locally.
58 // Typically, this method is used to (1) create an endpoint handle for the
59 // master interface; or (2) create an endpoint handle on receiving an
60 // interface ID from the message pipe.
61 ScopedInterfaceEndpointHandle CreateLocalEndpointHandle(InterfaceId id);
62
63 // Closes an interface endpoint handle.
64 void CloseEndpointHandle(InterfaceId id, bool is_local);
65
66 // Attaches an client to the specified endpoint to send and receive messages.
67 void AttachEndpointClient(const ScopedInterfaceEndpointHandle& handle,
68 InterfaceEndpointClient* endpoint_client);
69 // Detaches the client attached to the specified endpoint.
70 void DetachEndpointClient(const ScopedInterfaceEndpointHandle& handle);
71
72 bool SendMessage(const ScopedInterfaceEndpointHandle& handle,
73 Message* message);
74
75 // Raises an error on the underlying message pipe. It disconnects the pipe
76 // and notifies all interfaces running on this pipe.
77 void RaiseError();
78
79 // ---------------------------------------------------------------------------
80 // The following public methods are supposed to be called on the creating
81 // thread.
82
83 // Please note that this method shouldn't be called unless it results from an
84 // explicit request of the user of bindings (e.g., the user sets an
85 // InterfacePtr to null or closes a Binding).
86 void CloseMessagePipe() {
87 DCHECK(thread_checker_.CalledOnValidThread());
88 connector_.CloseMessagePipe();
89 }
90
91 // Extracts the underlying message pipe.
92 //
93 // TODO(yzshen): For now, users need to make sure there is no one holding on
94 // to associated interface endpoint handles at both sides of the message pipe
95 // in order to call this method. We need a way to forcefully invalidate
96 // associated interface endpoint handles.
97 ScopedMessagePipeHandle PassMessagePipe();
98
99 // Blocks the current thread until the first incoming message, or |deadline|.
100 bool WaitForIncomingMessage(MojoDeadline deadline) {
101 DCHECK(thread_checker_.CalledOnValidThread());
102 return connector_.WaitForIncomingMessage(deadline);
103 }
104
105 // See Binding for details of pause/resume.
106 void PauseIncomingMethodCallProcessing() {
107 DCHECK(thread_checker_.CalledOnValidThread());
108 connector_.PauseIncomingMethodCallProcessing();
109 }
110 void ResumeIncomingMethodCallProcessing() {
111 DCHECK(thread_checker_.CalledOnValidThread());
112 connector_.ResumeIncomingMethodCallProcessing();
113 }
114
115 // Sets this object to testing mode.
116 // In testing mode, the object doesn't disconnect the underlying message pipe
117 // when it receives unexpected or invalid messages.
118 void EnableTestingMode();
119
120 // Is the router bound to a message pipe handle?
121 bool is_valid() const {
122 DCHECK(thread_checker_.CalledOnValidThread());
123 return connector_.is_valid();
124 }
125
126 private:
127 friend class base::RefCountedDeleteOnMessageLoop<MultiplexRouter>;
128 friend class base::DeleteHelper<MultiplexRouter>;
129
130 class InterfaceEndpoint;
131 struct Task;
132
133 ~MultiplexRouter() override;
134
135 // MessageReceiver implementation:
136 bool Accept(Message* message) override;
137
138 // PipeControlMessageHandlerDelegate implementation:
139 bool OnPeerAssociatedEndpointClosed(InterfaceId id) override;
140 bool OnAssociatedEndpointClosedBeforeSent(InterfaceId id) override;
141
142 void OnPipeConnectionError();
143
144 // Processes enqueued tasks (incoming messages and error notifications).
145 // If |force_async| is true, it guarantees not to call any
146 // InterfaceEndpointClient methods directly.
147 //
148 // Note: Because calling into InterfaceEndpointClient may lead to destruction
149 // of this object, if |force_async| is set to false, the caller needs to hold
150 // on to a ref outside of |lock_| before calling this method.
151 void ProcessTasks(bool force_async);
152
153 // Returns true to indicate that |task| has been processed. Otherwise the task
154 // will be added back to the front of the queue.
155 // |*force_async| may be set to true to force subsequent tasks being processed
156 // in an asynchronous manner.
157 bool ProcessNotifyErrorTask(Task* task, bool* force_async);
158 bool ProcessIncomingMessageTask(Task* task, bool* force_async);
159
160 void LockAndCallProcessTasks();
161
162 void OnEndpointDestructed(InterfaceId id);
163
164 void RaiseErrorInNonTestingMode();
165
166 // Whether to set the namespace bit when generating interface IDs. Please see
167 // comments of kInterfaceIdNamespaceMask.
168 const bool set_interface_id_namespace_bit_;
169
170 MessageHeaderValidator header_validator_;
171 Connector connector_;
172
173 base::ThreadChecker thread_checker_;
174
175 // Protects the following members.
176 mutable base::Lock lock_;
177 PipeControlMessageHandler control_message_handler_;
178 PipeControlMessageProxy control_message_proxy_;
179
180 // Doesn't own the values. When an InterfaceEndpoint object is destructed, it
181 // notifies this object by calling OnEndpointDestructed().
182 std::map<InterfaceId, InterfaceEndpoint*> endpoints_;
183 uint32_t next_interface_id_value_;
184
185 // Owned objects.
186 std::deque<Task*> tasks_;
sky 2015/11/19 17:16:27 Can you make this a std::deque<scoped_ptr>?
yzshen1 2015/11/19 22:00:41 I don't think we can do that. IIUC, scoped_ptr mov
sky 2015/11/20 01:00:19 I believe scoped_ptr now supports the move operato
187
188 bool testing_mode_;
189 };
sky 2015/11/19 17:16:27 DISALLOW..
yzshen1 2015/11/19 22:00:40 Done.
190
191 } // namespace internal
192 } // namespace mojo
193
194 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MULTIPLEX_ROUTER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698