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 3 // found in the LICENSE file. 4 5 #ifndef MOJO_CORE_DISPATCHER_H_ 6 #define MOJO_CORE_DISPATCHER_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <ostream> 13 #include <vector> 14 15 #include "base/macros.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/strings/string_piece.h" 18 #include "base/synchronization/lock.h" 19 #include "mojo/core/handle_signals_state.h" 20 #include "mojo/core/ports/name.h" 21 #include "mojo/core/ports/port_ref.h" 22 #include "mojo/core/system_impl_export.h" 23 #include "mojo/core/watch.h" 24 #include "mojo/public/c/system/buffer.h" 25 #include "mojo/public/c/system/data_pipe.h" 26 #include "mojo/public/c/system/message_pipe.h" 27 #include "mojo/public/c/system/quota.h" 28 #include "mojo/public/c/system/trap.h" 29 #include "mojo/public/c/system/types.h" 30 #include "mojo/public/cpp/platform/platform_handle.h" 31 32 namespace mojo { 33 namespace core { 34 35 namespace ports { 36 class UserMessageEvent; 37 } 38 39 class Dispatcher; 40 class PlatformSharedMemoryMapping; 41 42 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>; 43 44 // A |Dispatcher| implements Mojo EDK calls that are associated with a 45 // particular MojoHandle. 46 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher 47 : public base::RefCountedThreadSafe<Dispatcher> { 48 public: 49 struct DispatcherInTransit { 50 DispatcherInTransit(); 51 DispatcherInTransit(const DispatcherInTransit& other); 52 ~DispatcherInTransit(); 53 54 scoped_refptr<Dispatcher> dispatcher; 55 MojoHandle local_handle; 56 }; 57 58 enum class Type { 59 UNKNOWN = 0, 60 MESSAGE_PIPE, 61 DATA_PIPE_PRODUCER, 62 DATA_PIPE_CONSUMER, 63 SHARED_BUFFER, 64 WATCHER, 65 INVITATION, 66 67 // "Private" types (not exposed via the public interface): 68 PLATFORM_HANDLE = -1, 69 }; 70 71 // All Dispatchers must minimally implement these methods. 72 73 virtual Type GetType() const = 0; 74 virtual MojoResult Close() = 0; 75 76 ///////////// Watcher API //////////////////// 77 78 virtual MojoResult WatchDispatcher(scoped_refptr<Dispatcher> dispatcher, 79 MojoHandleSignals signals, 80 MojoTriggerCondition condition, 81 uintptr_t context); 82 virtual MojoResult CancelWatch(uintptr_t context); 83 virtual MojoResult Arm(uint32_t* num_blocking_events, 84 MojoTrapEvent* blocking_events); 85 86 ///////////// Message pipe API ///////////// 87 88 virtual MojoResult WriteMessage( 89 std::unique_ptr<ports::UserMessageEvent> message); 90 91 virtual MojoResult ReadMessage( 92 std::unique_ptr<ports::UserMessageEvent>* message); 93 94 ///////////// Shared buffer API ///////////// 95 96 // |options| may be null. |new_dispatcher| must not be null, but 97 // |*new_dispatcher| should be null (and will contain the dispatcher for the 98 // new handle on success). 99 virtual MojoResult DuplicateBufferHandle( 100 const MojoDuplicateBufferHandleOptions* options, 101 scoped_refptr<Dispatcher>* new_dispatcher); 102 103 virtual MojoResult MapBuffer( 104 uint64_t offset, 105 uint64_t num_bytes, 106 std::unique_ptr<PlatformSharedMemoryMapping>* mapping); 107 108 virtual MojoResult GetBufferInfo(MojoSharedBufferInfo* info); 109 110 ///////////// Data pipe consumer API ///////////// 111 112 virtual MojoResult ReadData(const MojoReadDataOptions& options, 113 void* elements, 114 uint32_t* num_bytes); 115 116 virtual MojoResult BeginReadData(const void** buffer, 117 uint32_t* buffer_num_bytes); 118 119 virtual MojoResult EndReadData(uint32_t num_bytes_read); 120 121 ///////////// Data pipe producer API ///////////// 122 123 virtual MojoResult WriteData(const void* elements, 124 uint32_t* num_bytes, 125 const MojoWriteDataOptions& options); 126 127 virtual MojoResult BeginWriteData(void** buffer, uint32_t* buffer_num_bytes); 128 129 virtual MojoResult EndWriteData(uint32_t num_bytes_written); 130 131 // Invitation API. 132 virtual MojoResult AttachMessagePipe(base::StringPiece name, 133 ports::PortRef remote_peer_port); 134 virtual MojoResult ExtractMessagePipe(base::StringPiece name, 135 MojoHandle* message_pipe_handle); 136 137 // Quota API. 138 virtual MojoResult SetQuota(MojoQuotaType type, uint64_t limit); 139 virtual MojoResult QueryQuota(MojoQuotaType type, 140 uint64_t* limit, 141 uint64_t* usage); 142 143 ///////////// General-purpose API for all handle types ///////// 144 145 // Gets the current handle signals state. (The default implementation simply 146 // returns a default-constructed |HandleSignalsState|, i.e., no signals 147 // satisfied or satisfiable.) Note: The state is subject to change from other 148 // threads. 149 virtual HandleSignalsState GetHandleSignalsState() const; 150 151 // Adds a WatcherDispatcher reference to this dispatcher, to be notified of 152 // all subsequent changes to handle state including signal changes or closure. 153 // The reference is associated with a |context| for disambiguation of 154 // removals. 155 virtual MojoResult AddWatcherRef( 156 const scoped_refptr<WatcherDispatcher>& watcher, 157 uintptr_t context); 158 159 // Removes a WatcherDispatcher reference from this dispatcher. 160 virtual MojoResult RemoveWatcherRef(WatcherDispatcher* watcher, 161 uintptr_t context); 162 163 // Informs the caller of the total serialized size (in bytes) and the total 164 // number of platform handles and ports needed to transfer this dispatcher 165 // across a message pipe. 166 // 167 // Must eventually be followed by a call to EndSerializeAndClose(). Note that 168 // StartSerialize() and EndSerialize() are always called in sequence, and 169 // only between calls to BeginTransit() and either (but not both) 170 // CompleteTransitAndClose() or CancelTransit(). 171 // 172 // For this reason it is IMPERATIVE that the implementation ensure a 173 // consistent serializable state between BeginTransit() and 174 // CompleteTransitAndClose()/CancelTransit(). 175 virtual void StartSerialize(uint32_t* num_bytes, 176 uint32_t* num_ports, 177 uint32_t* num_platform_handles); 178 179 // Serializes this dispatcher into |destination|, |ports|, and |handles|. 180 // Returns true iff successful, false otherwise. In either case the dispatcher 181 // will close. 182 // 183 // NOTE: Transit MAY still fail after this call returns. Implementations 184 // should not assume PlatformHandle ownership has transferred until 185 // CompleteTransitAndClose() is called. In other words, if CancelTransit() is 186 // called, the implementation should retain its PlatformHandles in working 187 // condition. 188 virtual bool EndSerialize(void* destination, 189 ports::PortName* ports, 190 PlatformHandle* handles); 191 192 // Does whatever is necessary to begin transit of the dispatcher. This 193 // should return |true| if transit is OK, or false if the underlying resource 194 // is deemed busy by the implementation. 195 virtual bool BeginTransit(); 196 197 // Does whatever is necessary to complete transit of the dispatcher, including 198 // closure. This is only called upon successfully transmitting an outgoing 199 // message containing this serialized dispatcher. 200 virtual void CompleteTransitAndClose(); 201 202 // Does whatever is necessary to cancel transit of the dispatcher. The 203 // dispatcher should remain in a working state and resume normal operation. 204 virtual void CancelTransit(); 205 206 // Deserializes a specific dispatcher type from an incoming message. 207 static scoped_refptr<Dispatcher> Deserialize(Type type, 208 const void* bytes, 209 size_t num_bytes, 210 const ports::PortName* ports, 211 size_t num_ports, 212 PlatformHandle* platform_handles, 213 size_t platform_handle_count); 214 215 protected: 216 friend class base::RefCountedThreadSafe<Dispatcher>; 217 218 Dispatcher(); 219 virtual ~Dispatcher(); 220 221 DISALLOW_COPY_AND_ASSIGN(Dispatcher); 222 }; 223 224 // So logging macros and |DCHECK_EQ()|, etc. work. 225 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(std::ostream& out, 226 Dispatcher::Type type) { 227 return out << static_cast<int>(type); 228 } 229 230 } // namespace core 231 } // namespace mojo 232 233 #endif // MOJO_CORE_DISPATCHER_H_ 234