| 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 |