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

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

Powered by Google App Engine
This is Rietveld 408576698