1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 6 #define MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <queue> 12 13 #include "base/macros.h" 14 #include "mojo/edk/system/atomic_flag.h" 15 #include "mojo/edk/system/awakable_list.h" 16 #include "mojo/edk/system/dispatcher.h" 17 #include "mojo/edk/system/message_for_transit.h" 18 #include "mojo/edk/system/ports/port_ref.h" 19 20 namespace mojo { 21 namespace edk { 22 23 class NodeController; 24 25 class MessagePipeDispatcher : public Dispatcher { 26 public: 27 // Constructs a MessagePipeDispatcher permanently tied to a specific port. 28 // |connected| must indicate the state of the port at construction time; if 29 // the port is initialized with a peer, |connected| must be true. Otherwise it 30 // must be false. 31 // 32 // A MessagePipeDispatcher may not be transferred while in a disconnected 33 // state, and one can never return to a disconnected once connected. 34 // 35 // |pipe_id| is a unique identifier which can be used to track pipe endpoints 36 // as they're passed around. |endpoint| is either 0 or 1 and again is only 37 // used for tracking pipes (one side is always 0, the other is always 1.) 38 MessagePipeDispatcher(NodeController* node_controller, 39 const ports::PortRef& port, 40 uint64_t pipe_id, 41 int endpoint); 42 43 // Fuses this pipe with |other|. Returns |true| on success or |false| on 44 // failure. Regardless of the return value, both dispatchers are closed by 45 // this call. 46 bool Fuse(MessagePipeDispatcher* other); 47 48 // Dispatcher: 49 Type GetType() const override; 50 MojoResult Close() override; 51 MojoResult Watch(MojoHandleSignals signals, 52 const Watcher::WatchCallback& callback, 53 uintptr_t context) override; 54 MojoResult CancelWatch(uintptr_t context) override; 55 MojoResult WriteMessage(std::unique_ptr<MessageForTransit> message, 56 MojoWriteMessageFlags flags) override; 57 MojoResult ReadMessage(std::unique_ptr<MessageForTransit>* message, 58 uint32_t* num_bytes, 59 MojoHandle* handles, 60 uint32_t* num_handles, 61 MojoReadMessageFlags flags, 62 bool read_any_size) override; 63 HandleSignalsState GetHandleSignalsState() const override; 64 MojoResult AddAwakable(Awakable* awakable, 65 MojoHandleSignals signals, 66 uintptr_t context, 67 HandleSignalsState* signals_state) override; 68 void RemoveAwakable(Awakable* awakable, 69 HandleSignalsState* signals_state) override; 70 void StartSerialize(uint32_t* num_bytes, 71 uint32_t* num_ports, 72 uint32_t* num_handles) override; 73 bool EndSerialize(void* destination, 74 ports::PortName* ports, 75 PlatformHandle* handles) override; 76 bool BeginTransit() override; 77 void CompleteTransitAndClose() override; 78 void CancelTransit() override; 79 80 static scoped_refptr<Dispatcher> Deserialize( 81 const void* data, 82 size_t num_bytes, 83 const ports::PortName* ports, 84 size_t num_ports, 85 PlatformHandle* handles, 86 size_t num_handles); 87 88 private: 89 class PortObserverThunk; 90 friend class PortObserverThunk; 91 92 ~MessagePipeDispatcher() override; 93 94 MojoResult CloseNoLock(); 95 HandleSignalsState GetHandleSignalsStateNoLock() const; 96 void OnPortStatusChanged(); 97 98 // These are safe to access from any thread without locking. 99 NodeController* const node_controller_; 100 const ports::PortRef port_; 101 const uint64_t pipe_id_; 102 const int endpoint_; 103 104 // Guards access to all the fields below. 105 mutable base::Lock signal_lock_; 106 107 // This is not the same is |port_transferred_|. It's only held true between 108 // BeginTransit() and Complete/CancelTransit(). 109 AtomicFlag in_transit_; 110 111 bool port_transferred_ = false; 112 AtomicFlag port_closed_; 113 AwakableList awakables_; 114 115 DISALLOW_COPY_AND_ASSIGN(MessagePipeDispatcher); 116 }; 117 118 } // namespace edk 119 } // namespace mojo 120 121 #endif // MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 122