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

Side by Side Diff: mojo/edk/system/dispatcher.h

Issue 1350023003: Add a Mojo EDK for Chrome that uses one OS pipe per message pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move to mojo::edk namespace in preparation for runtim flag Created 5 years, 3 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MOJO_EDK_SYSTEM_DISPATCHER_H_ 5 #ifndef MOJO_EDK_SYSTEM_DISPATCHER_H_
6 #define MOJO_EDK_SYSTEM_DISPATCHER_H_ 6 #define MOJO_EDK_SYSTEM_DISPATCHER_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <ostream> 11 #include <ostream>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/synchronization/lock.h"
16 #include "mojo/edk/embedder/platform_handle_vector.h" 17 #include "mojo/edk/embedder/platform_handle_vector.h"
17 #include "mojo/edk/system/handle_signals_state.h" 18 #include "mojo/edk/system/handle_signals_state.h"
18 #include "mojo/edk/system/memory.h" 19 #include "mojo/edk/system/memory.h"
19 #include "mojo/edk/system/mutex.h"
20 #include "mojo/edk/system/system_impl_export.h" 20 #include "mojo/edk/system/system_impl_export.h"
21 #include "mojo/public/c/system/buffer.h" 21 #include "mojo/public/c/system/buffer.h"
22 #include "mojo/public/c/system/data_pipe.h" 22 #include "mojo/public/c/system/data_pipe.h"
23 #include "mojo/public/c/system/message_pipe.h" 23 #include "mojo/public/c/system/message_pipe.h"
24 #include "mojo/public/c/system/types.h" 24 #include "mojo/public/c/system/types.h"
25 #include "mojo/public/cpp/system/macros.h" 25 #include "mojo/public/cpp/system/macros.h"
26 26
27 namespace mojo { 27 namespace mojo {
28 namespace edk {
28 29
29 namespace embedder {
30 class PlatformSharedBufferMapping;
31 }
32
33 namespace system {
34
35 class Channel;
36 class Core; 30 class Core;
37 class Dispatcher; 31 class Dispatcher;
38 class DispatcherTransport; 32 class DispatcherTransport;
39 class HandleTable; 33 class HandleTable;
40 class LocalMessagePipeEndpoint; 34 class LocalMessagePipeEndpoint;
35 class PlatformSharedBufferMapping;
41 class ProxyMessagePipeEndpoint; 36 class ProxyMessagePipeEndpoint;
42 class TransportData; 37 class TransportData;
43 class Awakable; 38 class Awakable;
44 39
45 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>; 40 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>;
46 41
47 namespace test { 42 namespace test {
48 43
49 // Test helper. We need to declare it here so we can friend it. 44 // Test helper. We need to declare it here so we can friend it.
50 MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport 45 MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport
51 DispatcherTryStartTransport(Dispatcher* dispatcher); 46 DispatcherTryStartTransport(Dispatcher* dispatcher);
52 47
53 } // namespace test 48 } // namespace test
54 49
55 // A |Dispatcher| implements Mojo primitives that are "attached" to a particular 50 // A |Dispatcher| implements Mojo primitives that are "attached" to a particular
56 // handle. This includes most (all?) primitives except for |MojoWait...()|. This 51 // handle. This includes most (all?) primitives except for |MojoWait...()|. This
57 // object is thread-safe, with its state being protected by a single mutex 52 // object is thread-safe, with its state being protected by a single lock
58 // |mutex_|, which is also made available to implementation subclasses (via the 53 // |lock_|, which is also made available to implementation subclasses (via the
59 // |mutex()| method). 54 // |lock()| method).
60 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher 55 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
61 : public base::RefCountedThreadSafe<Dispatcher> { 56 : public base::RefCountedThreadSafe<Dispatcher> {
62 public: 57 public:
63 enum class Type { 58 enum class Type {
64 UNKNOWN = 0, 59 UNKNOWN = 0,
65 MESSAGE_PIPE, 60 MESSAGE_PIPE,
66 DATA_PIPE_PRODUCER, 61 DATA_PIPE_PRODUCER,
67 DATA_PIPE_CONSUMER, 62 DATA_PIPE_CONSUMER,
68 SHARED_BUFFER, 63 SHARED_BUFFER,
69 64
70 // "Private" types (not exposed via the public interface): 65 // "Private" types (not exposed via the public interface):
71 PLATFORM_HANDLE = -1 66 PLATFORM_HANDLE = -1
72 }; 67 };
73 virtual Type GetType() const = 0; 68 virtual Type GetType() const = 0;
74 69
75 // These methods implement the various primitives named |Mojo...()|. These 70 // These methods implement the various primitives named |Mojo...()|. These
76 // take |mutex_| and handle races with |Close()|. Then they call out to 71 // take |lock_| and handle races with |Close()|. Then they call out to
77 // subclasses' |...ImplNoLock()| methods (still under |mutex_|), which 72 // subclasses' |...ImplNoLock()| methods (still under |lock_|), which actually
78 // actually implement the primitives. 73 // implement the primitives.
79 // NOTE(vtl): This puts a big lock around each dispatcher (i.e., handle), and 74 // NOTE(vtl): This puts a big lock around each dispatcher (i.e., handle), and
80 // prevents the various |...ImplNoLock()|s from releasing the lock as soon as 75 // prevents the various |...ImplNoLock()|s from releasing the lock as soon as
81 // possible. If this becomes an issue, we can rethink this. 76 // possible. If this becomes an issue, we can rethink this.
82 MojoResult Close(); 77 MojoResult Close();
83 78
84 // |transports| may be non-null if and only if there are handles to be 79 // |transports| may be non-null if and only if there are handles to be
85 // written; not that |this| must not be in |transports|. On success, all the 80 // written; not that |this| must not be in |transports|. On success, all the
86 // dispatchers in |transports| must have been moved to a closed state; on 81 // dispatchers in |transports| must have been moved to a closed state; on
87 // failure, they should remain in their original state. 82 // failure, they should remain in their original state.
88 MojoResult WriteMessage(UserPointer<const void> bytes, 83 MojoResult WriteMessage(UserPointer<const void> bytes,
(...skipping 25 matching lines...) Expand all
114 // |options| may be null. |new_dispatcher| must not be null, but 109 // |options| may be null. |new_dispatcher| must not be null, but
115 // |*new_dispatcher| should be null (and will contain the dispatcher for the 110 // |*new_dispatcher| should be null (and will contain the dispatcher for the
116 // new handle on success). 111 // new handle on success).
117 MojoResult DuplicateBufferHandle( 112 MojoResult DuplicateBufferHandle(
118 UserPointer<const MojoDuplicateBufferHandleOptions> options, 113 UserPointer<const MojoDuplicateBufferHandleOptions> options,
119 scoped_refptr<Dispatcher>* new_dispatcher); 114 scoped_refptr<Dispatcher>* new_dispatcher);
120 MojoResult MapBuffer( 115 MojoResult MapBuffer(
121 uint64_t offset, 116 uint64_t offset,
122 uint64_t num_bytes, 117 uint64_t num_bytes,
123 MojoMapBufferFlags flags, 118 MojoMapBufferFlags flags,
124 scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping); 119 scoped_ptr<PlatformSharedBufferMapping>* mapping);
125 120
126 // Gets the current handle signals state. (The default implementation simply 121 // Gets the current handle signals state. (The default implementation simply
127 // returns a default-constructed |HandleSignalsState|, i.e., no signals 122 // returns a default-constructed |HandleSignalsState|, i.e., no signals
128 // satisfied or satisfiable.) Note: The state is subject to change from other 123 // satisfied or satisfiable.) Note: The state is subject to change from other
129 // threads. 124 // threads.
130 HandleSignalsState GetHandleSignalsState() const; 125 HandleSignalsState GetHandleSignalsState() const;
131 126
132 // Adds an awakable to this dispatcher, which will be woken up when this 127 // Adds an awakable to this dispatcher, which will be woken up when this
133 // object changes state to satisfy |signals| with context |context|. It will 128 // object changes state to satisfy |signals| with context |context|. It will
134 // also be woken up when it becomes impossible for the object to ever satisfy 129 // also be woken up when it becomes impossible for the object to ever satisfy
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // Tests also need this, to avoid needing |Core|. 163 // Tests also need this, to avoid needing |Core|.
169 friend DispatcherTransport test::DispatcherTryStartTransport(Dispatcher*); 164 friend DispatcherTransport test::DispatcherTryStartTransport(Dispatcher*);
170 165
171 // This must be called under the handle table lock and only if the handle 166 // This must be called under the handle table lock and only if the handle
172 // table entry is not marked busy. The caller must maintain a reference to 167 // table entry is not marked busy. The caller must maintain a reference to
173 // |dispatcher| until |DispatcherTransport::End()| is called. 168 // |dispatcher| until |DispatcherTransport::End()| is called.
174 static DispatcherTransport TryStartTransport(Dispatcher* dispatcher); 169 static DispatcherTransport TryStartTransport(Dispatcher* dispatcher);
175 }; 170 };
176 171
177 // A |TransportData| may serialize dispatchers that are given to it (and which 172 // A |TransportData| may serialize dispatchers that are given to it (and which
178 // were previously attached to the |MessageInTransit| that is creating it) to 173 // were previously attached to the |MessageInTransit| that is creating it) and
179 // a given |Channel| and then (probably in a different process) deserialize. 174 // and then (probably in a different process) deserialize.
180 // Note that the |MessageInTransit| "owns" (i.e., has the only ref to) these 175 // Note that the |MessageInTransit| "owns" (i.e., has the only ref to) these
181 // dispatchers, so there are no locking issues. (There's no lock ordering 176 // dispatchers, so there are no locking issues. (There's no lock ordering
182 // issue, and in fact no need to take dispatcher locks at all.) 177 // issue, and in fact no need to take dispatcher locks at all.)
183 // TODO(vtl): Consider making another wrapper similar to |DispatcherTransport| 178 // TODO(vtl): Consider making another wrapper similar to |DispatcherTransport|
184 // (but with an owning, unique reference), and having 179 // (but with an owning, unique reference), and having
185 // |CreateEquivalentDispatcherAndCloseImplNoLock()| return that wrapper (and 180 // |CreateEquivalentDispatcherAndCloseImplNoLock()| return that wrapper (and
186 // |MessageInTransit|, etc. only holding on to such wrappers). 181 // |MessageInTransit|, etc. only holding on to such wrappers).
187 class TransportDataAccess { 182 class TransportDataAccess {
188 private: 183 private:
189 friend class TransportData; 184 friend class TransportData;
190 185
191 // Serialization API. These functions may only be called on such 186 // Serialization API. These functions may only be called on such
192 // dispatchers. (|channel| is the |Channel| to which the dispatcher is to be 187 // dispatchers. See the |Dispatcher| methods of the same names for more
193 // serialized.) See the |Dispatcher| methods of the same names for more
194 // details. 188 // details.
195 static void StartSerialize(Dispatcher* dispatcher, 189 static void StartSerialize(Dispatcher* dispatcher,
196 Channel* channel,
197 size_t* max_size, 190 size_t* max_size,
198 size_t* max_platform_handles); 191 size_t* max_platform_handles);
199 static bool EndSerializeAndClose( 192 static bool EndSerializeAndClose(
200 Dispatcher* dispatcher, 193 Dispatcher* dispatcher,
201 Channel* channel,
202 void* destination, 194 void* destination,
203 size_t* actual_size, 195 size_t* actual_size,
204 embedder::PlatformHandleVector* platform_handles); 196 PlatformHandleVector* platform_handles);
205 197
206 // Deserialization API. 198 // Deserialization API.
207 // Note: This "clears" (i.e., reset to the invalid handle) any platform 199 // Note: This "clears" (i.e., reset to the invalid handle) any platform
208 // handles that it takes ownership of. 200 // handles that it takes ownership of.
209 static scoped_refptr<Dispatcher> Deserialize( 201 static scoped_refptr<Dispatcher> Deserialize(
210 Channel* channel,
211 int32_t type, 202 int32_t type,
212 const void* source, 203 const void* source,
213 size_t size, 204 size_t size,
214 embedder::PlatformHandleVector* platform_handles); 205 PlatformHandleVector* platform_handles);
215 }; 206 };
216 207
217 protected: 208 protected:
218 friend class base::RefCountedThreadSafe<Dispatcher>; 209 friend class base::RefCountedThreadSafe<Dispatcher>;
210 friend class MessagePipeDispatcher; // For TransportStarted/TransportEnded.
219 211
220 Dispatcher(); 212 Dispatcher();
221 virtual ~Dispatcher(); 213 virtual ~Dispatcher();
222 214
223 // These are to be overridden by subclasses (if necessary). They are called 215 // These are to be overridden by subclasses (if necessary). They are called
224 // exactly once (first |CancelAllAwakablesNoLock()|, then |CloseImplNoLock()|) 216 // exactly once -- first |CancelAllAwakablesNoLock()|, then
225 // when the dispatcher is being closed. 217 // |CloseImplNoLock()|,
226 virtual void CancelAllAwakablesNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 218 // when the dispatcher is being closed. They are called under |lock_|.
227 virtual void CloseImplNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 219 virtual void CancelAllAwakablesNoLock();
228 220 virtual void CloseImplNoLock();
229 virtual scoped_refptr<Dispatcher> 221 virtual scoped_refptr<Dispatcher>
230 CreateEquivalentDispatcherAndCloseImplNoLock() 222 CreateEquivalentDispatcherAndCloseImplNoLock() = 0;
231 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_) = 0;
232 223
233 // These are to be overridden by subclasses (if necessary). They are never 224 // These are to be overridden by subclasses (if necessary). They are never
234 // called after the dispatcher has been closed. See the descriptions of the 225 // called after the dispatcher has been closed. They are called under |lock_|.
235 // methods without the "ImplNoLock" for more information. 226 // See the descriptions of the methods without the "ImplNoLock" for more
227 // information.
236 virtual MojoResult WriteMessageImplNoLock( 228 virtual MojoResult WriteMessageImplNoLock(
237 UserPointer<const void> bytes, 229 UserPointer<const void> bytes,
238 uint32_t num_bytes, 230 uint32_t num_bytes,
239 std::vector<DispatcherTransport>* transports, 231 std::vector<DispatcherTransport>* transports,
240 MojoWriteMessageFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 232 MojoWriteMessageFlags flags);
241 virtual MojoResult ReadMessageImplNoLock(UserPointer<void> bytes, 233 virtual MojoResult ReadMessageImplNoLock(UserPointer<void> bytes,
242 UserPointer<uint32_t> num_bytes, 234 UserPointer<uint32_t> num_bytes,
243 DispatcherVector* dispatchers, 235 DispatcherVector* dispatchers,
244 uint32_t* num_dispatchers, 236 uint32_t* num_dispatchers,
245 MojoReadMessageFlags flags) 237 MojoReadMessageFlags flags);
246 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
247 virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements, 238 virtual MojoResult WriteDataImplNoLock(UserPointer<const void> elements,
248 UserPointer<uint32_t> num_bytes, 239 UserPointer<uint32_t> num_bytes,
249 MojoWriteDataFlags flags) 240 MojoWriteDataFlags flags);
250 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
251 virtual MojoResult BeginWriteDataImplNoLock( 241 virtual MojoResult BeginWriteDataImplNoLock(
252 UserPointer<void*> buffer, 242 UserPointer<void*> buffer,
253 UserPointer<uint32_t> buffer_num_bytes, 243 UserPointer<uint32_t> buffer_num_bytes,
254 MojoWriteDataFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 244 MojoWriteDataFlags flags);
255 virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written) 245 virtual MojoResult EndWriteDataImplNoLock(uint32_t num_bytes_written);
256 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
257 virtual MojoResult ReadDataImplNoLock(UserPointer<void> elements, 246 virtual MojoResult ReadDataImplNoLock(UserPointer<void> elements,
258 UserPointer<uint32_t> num_bytes, 247 UserPointer<uint32_t> num_bytes,
259 MojoReadDataFlags flags) 248 MojoReadDataFlags flags);
260 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
261 virtual MojoResult BeginReadDataImplNoLock( 249 virtual MojoResult BeginReadDataImplNoLock(
262 UserPointer<const void*> buffer, 250 UserPointer<const void*> buffer,
263 UserPointer<uint32_t> buffer_num_bytes, 251 UserPointer<uint32_t> buffer_num_bytes,
264 MojoReadDataFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 252 MojoReadDataFlags flags);
265 virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read) 253 virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read);
266 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
267 virtual MojoResult DuplicateBufferHandleImplNoLock( 254 virtual MojoResult DuplicateBufferHandleImplNoLock(
268 UserPointer<const MojoDuplicateBufferHandleOptions> options, 255 UserPointer<const MojoDuplicateBufferHandleOptions> options,
269 scoped_refptr<Dispatcher>* new_dispatcher) 256 scoped_refptr<Dispatcher>* new_dispatcher);
270 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
271 virtual MojoResult MapBufferImplNoLock( 257 virtual MojoResult MapBufferImplNoLock(
272 uint64_t offset, 258 uint64_t offset,
273 uint64_t num_bytes, 259 uint64_t num_bytes,
274 MojoMapBufferFlags flags, 260 MojoMapBufferFlags flags,
275 scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) 261 scoped_ptr<PlatformSharedBufferMapping>* mapping);
276 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 262 virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const;
277 virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const
278 MOJO_SHARED_LOCKS_REQUIRED(mutex_);
279 virtual MojoResult AddAwakableImplNoLock(Awakable* awakable, 263 virtual MojoResult AddAwakableImplNoLock(Awakable* awakable,
280 MojoHandleSignals signals, 264 MojoHandleSignals signals,
281 uint32_t context, 265 uint32_t context,
282 HandleSignalsState* signals_state) 266 HandleSignalsState* signals_state);
283 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
284 virtual void RemoveAwakableImplNoLock(Awakable* awakable, 267 virtual void RemoveAwakableImplNoLock(Awakable* awakable,
285 HandleSignalsState* signals_state) 268 HandleSignalsState* signals_state);
286 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
287 269
288 // These implement the API used to serialize dispatchers to a |Channel| 270 // These implement the API used to serialize dispatchers (described below).
289 // (described below). They will only be called on a dispatcher that's attached 271 // They will only be called on a dispatcher that's attached to and "owned" by
290 // to and "owned" by a |MessageInTransit|. See the non-"impl" versions for 272 // a |MessageInTransit|. See the non-"impl" versions for more information.
291 // more information.
292 // 273 //
293 // Note: |StartSerializeImplNoLock()| is actually called with |mutex_| NOT 274 // Note: |StartSerializeImplNoLock()| is actually called with |lock_| NOT
294 // held, since the dispatcher should only be accessible to the calling thread. 275 // held, since the dispatcher should only be accessible to the calling thread.
295 // On Debug builds, |EndSerializeAndCloseImplNoLock()| is called with |mutex_| 276 // On Debug builds, |EndSerializeAndCloseImplNoLock()| is called with |lock_|
296 // held, to satisfy any |mutex_.AssertHeld()| (e.g., in |CloseImplNoLock()| -- 277 // held, to satisfy any |lock_.AssertAcquired()| (e.g., in |CloseImplNoLock()|
297 // and anything it calls); disentangling those assertions is 278 // -- and anything it calls); disentangling those assertions is
298 // difficult/fragile, and would weaken our general checking of invariants. 279 // difficult/fragile, and would weaken our general checking of invariants.
299 // 280 //
300 // TODO(vtl): Consider making these pure virtual once most things support 281 // TODO(vtl): Consider making these pure virtual once most things support
301 // being passed over a message pipe. 282 // being passed over a message pipe.
302 virtual void StartSerializeImplNoLock(Channel* channel, 283 virtual void StartSerializeImplNoLock(size_t* max_size,
303 size_t* max_size, 284 size_t* max_platform_handles);
304 size_t* max_platform_handles)
305 MOJO_NOT_THREAD_SAFE;
306 virtual bool EndSerializeAndCloseImplNoLock( 285 virtual bool EndSerializeAndCloseImplNoLock(
307 Channel* channel,
308 void* destination, 286 void* destination,
309 size_t* actual_size, 287 size_t* actual_size,
310 embedder::PlatformHandleVector* platform_handles) MOJO_NOT_THREAD_SAFE; 288 PlatformHandleVector* platform_handles);
289
290 // These are called before and after a dispatcher is being transported. i.e.
291 // |TransportStarted| is called |StartSerializeImplNoLock| and
292 // |TransportEnded| is called after |EndSerializeAndCloseImplNoLock|. They are
293 // needed to avoid deadlocks when transporting a dispatcher. The reason is
294 // that |StartSerializeImplNoLock| is called on the main thread and will lead
295 // to calling RawChannel::ReleaseHandle. The dispatcher is locked and it will
296 // acquire RawChannel's locks as well. however the RawChannel could have its
297 // locks acquired on the IO thread and be waiting to acquire the dispatcher's
298 // lock. To solve this deadlock, |TransportStarted| is called before the
299 // dispatcher's lock is acquired.
300 virtual void TransportStarted() {}
301 virtual void TransportEnded() {}
311 302
312 // This should be overridden to return true if/when there's an ongoing 303 // This should be overridden to return true if/when there's an ongoing
313 // operation (e.g., two-phase read/writes on data pipes) that should prevent a 304 // operation (e.g., two-phase read/writes on data pipes) that should prevent a
314 // handle from being sent over a message pipe (with status "busy"). 305 // handle from being sent over a message pipe (with status "busy").
315 virtual bool IsBusyNoLock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_); 306 virtual bool IsBusyNoLock() const;
316 307
317 Mutex& mutex() const MOJO_LOCK_RETURNED(mutex_) { return mutex_; } 308 // Available to subclasses. (Note: Returns a non-const reference, just like
309 // |base::AutoLock|'s constructor takes a non-const reference.)
310 base::Lock& lock() const { return lock_; }
318 311
319 private: 312 private:
320 friend class DispatcherTransport; 313 friend class DispatcherTransport;
321 314
322 // Closes the dispatcher. This must be done under lock, and unlike |Close()|, 315 // Closes the dispatcher. This must be done under lock, and unlike |Close()|,
323 // the dispatcher must not be closed already. (This is the "equivalent" of 316 // the dispatcher must not be closed already. (This is the "equivalent" of
324 // |CreateEquivalentDispatcherAndCloseNoLock()|, for situations where the 317 // |CreateEquivalentDispatcherAndCloseNoLock()|, for situations where the
325 // dispatcher must be disposed of instead of "transferred".) 318 // dispatcher must be disposed of instead of "transferred".)
326 void CloseNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 319 void CloseNoLock();
327 320
328 // Creates an equivalent dispatcher -- representing the same resource as this 321 // Creates an equivalent dispatcher -- representing the same resource as this
329 // dispatcher -- and close (i.e., disable) this dispatcher. I.e., this 322 // dispatcher -- and close (i.e., disable) this dispatcher. I.e., this
330 // dispatcher will look as though it was closed, but the resource it 323 // dispatcher will look as though it was closed, but the resource it
331 // represents will be assigned to the new dispatcher. This must be called 324 // represents will be assigned to the new dispatcher. This must be called
332 // under the dispatcher's lock. 325 // under the dispatcher's lock.
333 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock() 326 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock();
334 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
335 327
336 // API to serialize dispatchers to a |Channel|, exposed to only 328 // API to serialize dispatchers, exposed to only |TransportData| (via
337 // |TransportData| (via |TransportData|). They may only be called on a 329 // |TransportData|). They may only be called on a dispatcher attached to a
338 // dispatcher attached to a |MessageInTransit| (and in particular not in 330 // |MessageInTransit| (and in particular not in |CoreImpl|'s handle table).
339 // |CoreImpl|'s handle table).
340 //
341 // TODO(vtl): The serialization API (and related implementation methods,
342 // including |DispatcherTransport|'s methods) is marked
343 // |MOJO_NOT_THREAD_SAFE|. This is because the threading requirements are
344 // somewhat complicated (e.g., |HandleTableAccess::TryStartTransport()| is
345 // really a try-lock function, amongst other things). We could/should do a
346 // more careful job annotating these methods.
347 // https://github.com/domokit/mojo/issues/322
348 // 331 //
349 // Starts the serialization. Returns (via the two "out" parameters) the 332 // Starts the serialization. Returns (via the two "out" parameters) the
350 // maximum amount of space that may be needed to serialize this dispatcher to 333 // maximum amount of space that may be needed to serialize this dispatcher (no
351 // the given |Channel| (no more than 334 // more than |TransportData::kMaxSerializedDispatcherSize|) and the maximum
352 // |TransportData::kMaxSerializedDispatcherSize|) and the maximum number of 335 // number of |PlatformHandle|s that may need to be attached (no more than
353 // |PlatformHandle|s that may need to be attached (no more than
354 // |TransportData::kMaxSerializedDispatcherPlatformHandles|). If this 336 // |TransportData::kMaxSerializedDispatcherPlatformHandles|). If this
355 // dispatcher cannot be serialized to the given |Channel|, |*max_size| and 337 // dispatcher cannot be serialized, |*max_size| and |*max_platform_handles|
356 // |*max_platform_handles| should be set to zero. A call to this method will 338 // should be set to zero. A call to this method will ALWAYS be followed by a
357 // ALWAYS be followed by a call to |EndSerializeAndClose()| (even if this 339 // call to |EndSerializeAndClose()| (even if this dispatcher cannot be
358 // dispatcher cannot be serialized to the given |Channel|). 340 // serialized).
359 void StartSerialize(Channel* channel, 341 void StartSerialize(size_t* max_size,
360 size_t* max_size, 342 size_t* max_platform_handles);
361 size_t* max_platform_handles) MOJO_NOT_THREAD_SAFE; 343 // Completes the serialization of this dispatcher and closes it. (This call
362 // Completes the serialization of this dispatcher to the given |Channel| and 344 // will always follow an earlier call to |StartSerialize()|. This does so by
363 // closes it. (This call will always follow an earlier call to 345 // writing to |destination| and appending any |PlatformHandle|s needed to
364 // |StartSerialize()|, with the same |Channel|.) This does so by writing to
365 // |destination| and appending any |PlatformHandle|s needed to
366 // |platform_handles| (which may be null if no platform handles were indicated 346 // |platform_handles| (which may be null if no platform handles were indicated
367 // to be required to |StartSerialize()|). This may write no more than the 347 // to be required to |StartSerialize()|). This may write no more than the
368 // amount indicated by |StartSerialize()|. (WARNING: Beware of races, e.g., if 348 // amount indicated by |StartSerialize()|. (WARNING: Beware of races, e.g., if
369 // something can be mutated between the two calls!) Returns true on success, 349 // something can be mutated between the two calls!) Returns true on success,
370 // in which case |*actual_size| is set to the amount it actually wrote to 350 // in which case |*actual_size| is set to the amount it actually wrote to
371 // |destination|. On failure, |*actual_size| should not be modified; however, 351 // |destination|. On failure, |*actual_size| should not be modified; however,
372 // the dispatcher will still be closed. 352 // the dispatcher will still be closed.
373 bool EndSerializeAndClose(Channel* channel, 353 bool EndSerializeAndClose(void* destination,
374 void* destination,
375 size_t* actual_size, 354 size_t* actual_size,
376 embedder::PlatformHandleVector* platform_handles) 355 PlatformHandleVector* platform_handles);
377 MOJO_NOT_THREAD_SAFE;
378 356
379 // This protects the following members as well as any state added by 357 // This protects the following members as well as any state added by
380 // subclasses. 358 // subclasses.
381 mutable Mutex mutex_; 359 mutable base::Lock lock_;
382 bool is_closed_ MOJO_GUARDED_BY(mutex_); 360 bool is_closed_;
383 361
384 MOJO_DISALLOW_COPY_AND_ASSIGN(Dispatcher); 362 MOJO_DISALLOW_COPY_AND_ASSIGN(Dispatcher);
385 }; 363 };
386 364
387 // Wrapper around a |Dispatcher| pointer, while it's being processed to be 365 // Wrapper around a |Dispatcher| pointer, while it's being processed to be
388 // passed in a message pipe. See the comment about 366 // passed in a message pipe. See the comment about
389 // |Dispatcher::HandleTableAccess| for more details. 367 // |Dispatcher::HandleTableAccess| for more details.
390 // 368 //
391 // Note: This class is deliberately "thin" -- no more expensive than a 369 // Note: This class is deliberately "thin" -- no more expensive than a
392 // |Dispatcher*|. 370 // |Dispatcher*|.
393 class MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport { 371 class MOJO_SYSTEM_IMPL_EXPORT DispatcherTransport {
394 public: 372 public:
395 DispatcherTransport() : dispatcher_(nullptr) {} 373 DispatcherTransport() : dispatcher_(nullptr) {}
396 374
397 void End() MOJO_NOT_THREAD_SAFE; 375 void End();
398 376
399 Dispatcher::Type GetType() const { return dispatcher_->GetType(); } 377 Dispatcher::Type GetType() const { return dispatcher_->GetType(); }
400 bool IsBusy() const MOJO_NOT_THREAD_SAFE { 378 bool IsBusy() const { return dispatcher_->IsBusyNoLock(); }
401 return dispatcher_->IsBusyNoLock(); 379 void Close() { dispatcher_->CloseNoLock(); }
402 } 380 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndClose() {
403 void Close() MOJO_NOT_THREAD_SAFE { dispatcher_->CloseNoLock(); }
404 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndClose()
405 MOJO_NOT_THREAD_SAFE {
406 return dispatcher_->CreateEquivalentDispatcherAndCloseNoLock(); 381 return dispatcher_->CreateEquivalentDispatcherAndCloseNoLock();
407 } 382 }
408 383
409 bool is_valid() const { return !!dispatcher_; } 384 bool is_valid() const { return !!dispatcher_; }
410 385
411 protected: 386 protected:
412 Dispatcher* dispatcher() { return dispatcher_; } 387 Dispatcher* dispatcher() { return dispatcher_; }
413 388
414 private: 389 private:
415 friend class Dispatcher::HandleTableAccess; 390 friend class Dispatcher::HandleTableAccess;
391 friend class MessagePipeDispatcher; // For AttachTransportsNoLock.
416 392
417 explicit DispatcherTransport(Dispatcher* dispatcher) 393 explicit DispatcherTransport(Dispatcher* dispatcher)
418 : dispatcher_(dispatcher) {} 394 : dispatcher_(dispatcher) {}
419 395
420 Dispatcher* dispatcher_; 396 Dispatcher* dispatcher_;
421 397
422 // Copy and assign allowed. 398 // Copy and assign allowed.
423 }; 399 };
424 400
425 // So logging macros and |DCHECK_EQ()|, etc. work. 401 // So logging macros and |DCHECK_EQ()|, etc. work.
426 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(std::ostream& out, 402 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(std::ostream& out,
427 Dispatcher::Type type) { 403 Dispatcher::Type type) {
428 return out << static_cast<int>(type); 404 return out << static_cast<int>(type);
429 } 405 }
430 406
431 } // namespace system 407 } // namespace edk
432 } // namespace mojo 408 } // namespace mojo
433 409
434 #endif // MOJO_EDK_SYSTEM_DISPATCHER_H_ 410 #endif // MOJO_EDK_SYSTEM_DISPATCHER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698