OLD | NEW |
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 <memory> | 11 #include <memory> |
12 #include <ostream> | 12 #include <ostream> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/memory/ref_counted.h" | |
16 #include "mojo/edk/embedder/platform_handle_vector.h" | 15 #include "mojo/edk/embedder/platform_handle_vector.h" |
17 #include "mojo/edk/system/handle_signals_state.h" | 16 #include "mojo/edk/system/handle_signals_state.h" |
18 #include "mojo/edk/system/memory.h" | 17 #include "mojo/edk/system/memory.h" |
19 #include "mojo/edk/system/mutex.h" | 18 #include "mojo/edk/system/mutex.h" |
| 19 #include "mojo/edk/system/ref_counted.h" |
| 20 #include "mojo/edk/system/ref_ptr.h" |
20 #include "mojo/public/c/system/buffer.h" | 21 #include "mojo/public/c/system/buffer.h" |
21 #include "mojo/public/c/system/data_pipe.h" | 22 #include "mojo/public/c/system/data_pipe.h" |
22 #include "mojo/public/c/system/message_pipe.h" | 23 #include "mojo/public/c/system/message_pipe.h" |
23 #include "mojo/public/c/system/types.h" | 24 #include "mojo/public/c/system/types.h" |
24 #include "mojo/public/cpp/system/macros.h" | 25 #include "mojo/public/cpp/system/macros.h" |
25 | 26 |
26 namespace mojo { | 27 namespace mojo { |
27 | 28 |
28 namespace embedder { | 29 namespace embedder { |
29 class PlatformSharedBufferMapping; | 30 class PlatformSharedBufferMapping; |
30 } | 31 } |
31 | 32 |
32 namespace system { | 33 namespace system { |
33 | 34 |
34 class Channel; | 35 class Channel; |
35 class Core; | 36 class Core; |
36 class Dispatcher; | 37 class Dispatcher; |
37 class DispatcherTransport; | 38 class DispatcherTransport; |
38 class HandleTable; | 39 class HandleTable; |
39 class LocalMessagePipeEndpoint; | 40 class LocalMessagePipeEndpoint; |
40 class ProxyMessagePipeEndpoint; | 41 class ProxyMessagePipeEndpoint; |
41 class TransportData; | 42 class TransportData; |
42 class Awakable; | 43 class Awakable; |
43 | 44 |
44 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>; | 45 using DispatcherVector = std::vector<RefPtr<Dispatcher>>; |
45 | 46 |
46 namespace test { | 47 namespace test { |
47 | 48 |
48 // Test helper. We need to declare it here so we can friend it. | 49 // Test helper. We need to declare it here so we can friend it. |
49 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher); | 50 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher); |
50 | 51 |
51 } // namespace test | 52 } // namespace test |
52 | 53 |
53 // A |Dispatcher| implements Mojo primitives that are "attached" to a particular | 54 // A |Dispatcher| implements Mojo primitives that are "attached" to a particular |
54 // handle. This includes most (all?) primitives except for |MojoWait...()|. This | 55 // handle. This includes most (all?) primitives except for |MojoWait...()|. This |
55 // 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 mutex |
56 // |mutex_|, which is also made available to implementation subclasses (via the | 57 // |mutex_|, which is also made available to implementation subclasses (via the |
57 // |mutex()| method). | 58 // |mutex()| method). |
58 class Dispatcher : public base::RefCountedThreadSafe<Dispatcher> { | 59 class Dispatcher : public RefCountedThreadSafe<Dispatcher> { |
59 public: | 60 public: |
60 enum class Type { | 61 enum class Type { |
61 UNKNOWN = 0, | 62 UNKNOWN = 0, |
62 MESSAGE_PIPE, | 63 MESSAGE_PIPE, |
63 DATA_PIPE_PRODUCER, | 64 DATA_PIPE_PRODUCER, |
64 DATA_PIPE_CONSUMER, | 65 DATA_PIPE_CONSUMER, |
65 SHARED_BUFFER, | 66 SHARED_BUFFER, |
66 | 67 |
67 // "Private" types (not exposed via the public interface): | 68 // "Private" types (not exposed via the public interface): |
68 PLATFORM_HANDLE = -1 | 69 PLATFORM_HANDLE = -1 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 MojoReadDataFlags flags); | 107 MojoReadDataFlags flags); |
107 MojoResult BeginReadData(UserPointer<const void*> buffer, | 108 MojoResult BeginReadData(UserPointer<const void*> buffer, |
108 UserPointer<uint32_t> buffer_num_bytes, | 109 UserPointer<uint32_t> buffer_num_bytes, |
109 MojoReadDataFlags flags); | 110 MojoReadDataFlags flags); |
110 MojoResult EndReadData(uint32_t num_bytes_read); | 111 MojoResult EndReadData(uint32_t num_bytes_read); |
111 // |options| may be null. |new_dispatcher| must not be null, but | 112 // |options| may be null. |new_dispatcher| must not be null, but |
112 // |*new_dispatcher| should be null (and will contain the dispatcher for the | 113 // |*new_dispatcher| should be null (and will contain the dispatcher for the |
113 // new handle on success). | 114 // new handle on success). |
114 MojoResult DuplicateBufferHandle( | 115 MojoResult DuplicateBufferHandle( |
115 UserPointer<const MojoDuplicateBufferHandleOptions> options, | 116 UserPointer<const MojoDuplicateBufferHandleOptions> options, |
116 scoped_refptr<Dispatcher>* new_dispatcher); | 117 RefPtr<Dispatcher>* new_dispatcher); |
117 MojoResult MapBuffer( | 118 MojoResult MapBuffer( |
118 uint64_t offset, | 119 uint64_t offset, |
119 uint64_t num_bytes, | 120 uint64_t num_bytes, |
120 MojoMapBufferFlags flags, | 121 MojoMapBufferFlags flags, |
121 std::unique_ptr<embedder::PlatformSharedBufferMapping>* mapping); | 122 std::unique_ptr<embedder::PlatformSharedBufferMapping>* mapping); |
122 | 123 |
123 // Gets the current handle signals state. (The default implementation simply | 124 // Gets the current handle signals state. (The default implementation simply |
124 // returns a default-constructed |HandleSignalsState|, i.e., no signals | 125 // returns a default-constructed |HandleSignalsState|, i.e., no signals |
125 // satisfied or satisfiable.) Note: The state is subject to change from other | 126 // satisfied or satisfiable.) Note: The state is subject to change from other |
126 // threads. | 127 // threads. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 static bool EndSerializeAndClose( | 197 static bool EndSerializeAndClose( |
197 Dispatcher* dispatcher, | 198 Dispatcher* dispatcher, |
198 Channel* channel, | 199 Channel* channel, |
199 void* destination, | 200 void* destination, |
200 size_t* actual_size, | 201 size_t* actual_size, |
201 embedder::PlatformHandleVector* platform_handles); | 202 embedder::PlatformHandleVector* platform_handles); |
202 | 203 |
203 // Deserialization API. | 204 // Deserialization API. |
204 // Note: This "clears" (i.e., reset to the invalid handle) any platform | 205 // Note: This "clears" (i.e., reset to the invalid handle) any platform |
205 // handles that it takes ownership of. | 206 // handles that it takes ownership of. |
206 static scoped_refptr<Dispatcher> Deserialize( | 207 static RefPtr<Dispatcher> Deserialize( |
207 Channel* channel, | 208 Channel* channel, |
208 int32_t type, | 209 int32_t type, |
209 const void* source, | 210 const void* source, |
210 size_t size, | 211 size_t size, |
211 embedder::PlatformHandleVector* platform_handles); | 212 embedder::PlatformHandleVector* platform_handles); |
212 }; | 213 }; |
213 | 214 |
214 protected: | 215 protected: |
215 friend class base::RefCountedThreadSafe<Dispatcher>; | |
216 | |
217 Dispatcher(); | 216 Dispatcher(); |
218 virtual ~Dispatcher(); | 217 virtual ~Dispatcher(); |
219 | 218 |
220 // 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 |
221 // exactly once (first |CancelAllAwakablesNoLock()|, then |CloseImplNoLock()|) | 220 // exactly once (first |CancelAllAwakablesNoLock()|, then |CloseImplNoLock()|) |
222 // when the dispatcher is being closed. | 221 // when the dispatcher is being closed. |
223 virtual void CancelAllAwakablesNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 222 virtual void CancelAllAwakablesNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
224 virtual void CloseImplNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 223 virtual void CloseImplNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
225 | 224 |
226 virtual scoped_refptr<Dispatcher> | 225 virtual RefPtr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock() |
227 CreateEquivalentDispatcherAndCloseImplNoLock() | |
228 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_) = 0; | 226 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_) = 0; |
229 | 227 |
230 // 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 |
231 // called after the dispatcher has been closed. See the descriptions of the | 229 // called after the dispatcher has been closed. See the descriptions of the |
232 // methods without the "ImplNoLock" for more information. | 230 // methods without the "ImplNoLock" for more information. |
233 virtual MojoResult WriteMessageImplNoLock( | 231 virtual MojoResult WriteMessageImplNoLock( |
234 UserPointer<const void> bytes, | 232 UserPointer<const void> bytes, |
235 uint32_t num_bytes, | 233 uint32_t num_bytes, |
236 std::vector<DispatcherTransport>* transports, | 234 std::vector<DispatcherTransport>* transports, |
237 MojoWriteMessageFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 235 MojoWriteMessageFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
(...skipping 18 matching lines...) Expand all Loading... |
256 MojoReadDataFlags flags) | 254 MojoReadDataFlags flags) |
257 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 255 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
258 virtual MojoResult BeginReadDataImplNoLock( | 256 virtual MojoResult BeginReadDataImplNoLock( |
259 UserPointer<const void*> buffer, | 257 UserPointer<const void*> buffer, |
260 UserPointer<uint32_t> buffer_num_bytes, | 258 UserPointer<uint32_t> buffer_num_bytes, |
261 MojoReadDataFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 259 MojoReadDataFlags flags) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
262 virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read) | 260 virtual MojoResult EndReadDataImplNoLock(uint32_t num_bytes_read) |
263 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 261 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
264 virtual MojoResult DuplicateBufferHandleImplNoLock( | 262 virtual MojoResult DuplicateBufferHandleImplNoLock( |
265 UserPointer<const MojoDuplicateBufferHandleOptions> options, | 263 UserPointer<const MojoDuplicateBufferHandleOptions> options, |
266 scoped_refptr<Dispatcher>* new_dispatcher) | 264 RefPtr<Dispatcher>* new_dispatcher) MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
267 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | |
268 virtual MojoResult MapBufferImplNoLock( | 265 virtual MojoResult MapBufferImplNoLock( |
269 uint64_t offset, | 266 uint64_t offset, |
270 uint64_t num_bytes, | 267 uint64_t num_bytes, |
271 MojoMapBufferFlags flags, | 268 MojoMapBufferFlags flags, |
272 std::unique_ptr<embedder::PlatformSharedBufferMapping>* mapping) | 269 std::unique_ptr<embedder::PlatformSharedBufferMapping>* mapping) |
273 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 270 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
274 virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const | 271 virtual HandleSignalsState GetHandleSignalsStateImplNoLock() const |
275 MOJO_SHARED_LOCKS_REQUIRED(mutex_); | 272 MOJO_SHARED_LOCKS_REQUIRED(mutex_); |
276 virtual MojoResult AddAwakableImplNoLock(Awakable* awakable, | 273 virtual MojoResult AddAwakableImplNoLock(Awakable* awakable, |
277 MojoHandleSignals signals, | 274 MojoHandleSignals signals, |
(...skipping 29 matching lines...) Expand all Loading... |
307 embedder::PlatformHandleVector* platform_handles) MOJO_NOT_THREAD_SAFE; | 304 embedder::PlatformHandleVector* platform_handles) MOJO_NOT_THREAD_SAFE; |
308 | 305 |
309 // This should be overridden to return true if/when there's an ongoing | 306 // This should be overridden to return true if/when there's an ongoing |
310 // operation (e.g., two-phase read/writes on data pipes) that should prevent a | 307 // operation (e.g., two-phase read/writes on data pipes) that should prevent a |
311 // handle from being sent over a message pipe (with status "busy"). | 308 // handle from being sent over a message pipe (with status "busy"). |
312 virtual bool IsBusyNoLock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_); | 309 virtual bool IsBusyNoLock() const MOJO_SHARED_LOCKS_REQUIRED(mutex_); |
313 | 310 |
314 Mutex& mutex() const MOJO_LOCK_RETURNED(mutex_) { return mutex_; } | 311 Mutex& mutex() const MOJO_LOCK_RETURNED(mutex_) { return mutex_; } |
315 | 312 |
316 private: | 313 private: |
| 314 FRIEND_REF_COUNTED_THREAD_SAFE(Dispatcher); |
317 friend class DispatcherTransport; | 315 friend class DispatcherTransport; |
318 | 316 |
319 // Closes the dispatcher. This must be done under lock, and unlike |Close()|, | 317 // Closes the dispatcher. This must be done under lock, and unlike |Close()|, |
320 // the dispatcher must not be closed already. (This is the "equivalent" of | 318 // the dispatcher must not be closed already. (This is the "equivalent" of |
321 // |CreateEquivalentDispatcherAndCloseNoLock()|, for situations where the | 319 // |CreateEquivalentDispatcherAndCloseNoLock()|, for situations where the |
322 // dispatcher must be disposed of instead of "transferred".) | 320 // dispatcher must be disposed of instead of "transferred".) |
323 void CloseNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 321 void CloseNoLock() MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
324 | 322 |
325 // Creates an equivalent dispatcher -- representing the same resource as this | 323 // Creates an equivalent dispatcher -- representing the same resource as this |
326 // dispatcher -- and close (i.e., disable) this dispatcher. I.e., this | 324 // dispatcher -- and close (i.e., disable) this dispatcher. I.e., this |
327 // dispatcher will look as though it was closed, but the resource it | 325 // dispatcher will look as though it was closed, but the resource it |
328 // represents will be assigned to the new dispatcher. This must be called | 326 // represents will be assigned to the new dispatcher. This must be called |
329 // under the dispatcher's lock. | 327 // under the dispatcher's lock. |
330 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock() | 328 RefPtr<Dispatcher> CreateEquivalentDispatcherAndCloseNoLock() |
331 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); | 329 MOJO_EXCLUSIVE_LOCKS_REQUIRED(mutex_); |
332 | 330 |
333 // API to serialize dispatchers to a |Channel|, exposed to only | 331 // API to serialize dispatchers to a |Channel|, exposed to only |
334 // |TransportData| (via |TransportData|). They may only be called on a | 332 // |TransportData| (via |TransportData|). They may only be called on a |
335 // dispatcher attached to a |MessageInTransit| (and in particular not in | 333 // dispatcher attached to a |MessageInTransit| (and in particular not in |
336 // |CoreImpl|'s handle table). | 334 // |CoreImpl|'s handle table). |
337 // | 335 // |
338 // TODO(vtl): The serialization API (and related implementation methods, | 336 // TODO(vtl): The serialization API (and related implementation methods, |
339 // including |DispatcherTransport|'s methods) is marked | 337 // including |DispatcherTransport|'s methods) is marked |
340 // |MOJO_NOT_THREAD_SAFE|. This is because the threading requirements are | 338 // |MOJO_NOT_THREAD_SAFE|. This is because the threading requirements are |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 public: | 389 public: |
392 DispatcherTransport() : dispatcher_(nullptr) {} | 390 DispatcherTransport() : dispatcher_(nullptr) {} |
393 | 391 |
394 void End() MOJO_NOT_THREAD_SAFE; | 392 void End() MOJO_NOT_THREAD_SAFE; |
395 | 393 |
396 Dispatcher::Type GetType() const { return dispatcher_->GetType(); } | 394 Dispatcher::Type GetType() const { return dispatcher_->GetType(); } |
397 bool IsBusy() const MOJO_NOT_THREAD_SAFE { | 395 bool IsBusy() const MOJO_NOT_THREAD_SAFE { |
398 return dispatcher_->IsBusyNoLock(); | 396 return dispatcher_->IsBusyNoLock(); |
399 } | 397 } |
400 void Close() MOJO_NOT_THREAD_SAFE { dispatcher_->CloseNoLock(); } | 398 void Close() MOJO_NOT_THREAD_SAFE { dispatcher_->CloseNoLock(); } |
401 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndClose() | 399 RefPtr<Dispatcher> CreateEquivalentDispatcherAndClose() MOJO_NOT_THREAD_SAFE { |
402 MOJO_NOT_THREAD_SAFE { | |
403 return dispatcher_->CreateEquivalentDispatcherAndCloseNoLock(); | 400 return dispatcher_->CreateEquivalentDispatcherAndCloseNoLock(); |
404 } | 401 } |
405 | 402 |
406 bool is_valid() const { return !!dispatcher_; } | 403 bool is_valid() const { return !!dispatcher_; } |
407 | 404 |
408 protected: | 405 protected: |
409 Dispatcher* dispatcher() { return dispatcher_; } | 406 Dispatcher* dispatcher() { return dispatcher_; } |
410 | 407 |
411 private: | 408 private: |
412 friend class Dispatcher::HandleTableAccess; | 409 friend class Dispatcher::HandleTableAccess; |
413 | 410 |
414 explicit DispatcherTransport(Dispatcher* dispatcher) | 411 explicit DispatcherTransport(Dispatcher* dispatcher) |
415 : dispatcher_(dispatcher) {} | 412 : dispatcher_(dispatcher) {} |
416 | 413 |
417 Dispatcher* dispatcher_; | 414 Dispatcher* dispatcher_; |
418 | 415 |
419 // Copy and assign allowed. | 416 // Copy and assign allowed. |
420 }; | 417 }; |
421 | 418 |
422 // So logging macros and |DCHECK_EQ()|, etc. work. | 419 // So logging macros and |DCHECK_EQ()|, etc. work. |
423 inline std::ostream& operator<<(std::ostream& out, Dispatcher::Type type) { | 420 inline std::ostream& operator<<(std::ostream& out, Dispatcher::Type type) { |
424 return out << static_cast<int>(type); | 421 return out << static_cast<int>(type); |
425 } | 422 } |
426 | 423 |
427 } // namespace system | 424 } // namespace system |
428 } // namespace mojo | 425 } // namespace mojo |
429 | 426 |
430 #endif // MOJO_EDK_SYSTEM_DISPATCHER_H_ | 427 #endif // MOJO_EDK_SYSTEM_DISPATCHER_H_ |
OLD | NEW |