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