Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 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_CHANNEL_H_ | |
| 6 #define MOJO_EDK_SYSTEM_CHANNEL_H_ | |
| 7 | |
| 8 #include "base/logging.h" | |
| 9 #include "base/macros.h" | |
| 10 #include "base/memory/ref_counted.h" | |
| 11 #include "base/task_runner.h" | |
| 12 #include "mojo/edk/embedder/platform_handle_vector.h" | |
| 13 #include "mojo/edk/embedder/scoped_platform_handle.h" | |
| 14 | |
| 15 namespace mojo { | |
| 16 namespace edk { | |
| 17 | |
| 18 const size_t kChannelMessageAlignment = 8; | |
| 19 | |
| 20 // Channel provides a thread-safe interface to read and write arbitrary | |
| 21 // delimited messages over an underlying I/O channel, optionally transferring | |
| 22 // one or more platform handles in the process. | |
| 23 class Channel : public base::RefCountedThreadSafe<Channel> { | |
| 24 public: | |
| 25 struct Message; | |
| 26 | |
| 27 using MessagePtr = scoped_ptr<Message>; | |
| 28 | |
| 29 // A message to be written to a channel. | |
| 30 struct Message { | |
| 31 struct Header { | |
| 32 // Message size in bytes, including the header. | |
| 33 uint32_t num_bytes; | |
| 34 | |
| 35 // Number of attached handles. | |
| 36 uint16_t num_handles; | |
| 37 | |
| 38 // Zero | |
| 39 uint16_t padding; | |
| 40 }; | |
| 41 | |
| 42 // Allocates and owns a buffer for message data with enough capacity for | |
| 43 // |payload_size| bytes plus a header. Takes ownership of |handles|, which | |
| 44 // may be null. | |
| 45 Message(size_t payload_size, size_t num_handles); | |
| 46 | |
| 47 ~Message(); | |
| 48 | |
| 49 // Constructs a Message from serialized message data. | |
| 50 static MessagePtr Deserialize(const void* data, size_t data_num_bytes); | |
| 51 | |
| 52 const void* data() const { return data_; } | |
| 53 size_t data_num_bytes() const { return size_; } | |
| 54 | |
| 55 void* mutable_payload() { return static_cast<void*>(header_ + 1); } | |
| 56 const void* payload() const { | |
| 57 return static_cast<const void*>(header_ + 1); | |
| 58 } | |
| 59 size_t payload_size() const; | |
| 60 | |
| 61 size_t num_handles() const { return header_->num_handles; } | |
| 62 bool has_handles() const { return header_->num_handles > 0; } | |
| 63 PlatformHandle* handles(); | |
| 64 | |
| 65 // Note: SetHandles() and TakeHandles() invalidate any previous value of | |
| 66 // handles(). | |
| 67 void SetHandles(ScopedPlatformHandleVectorPtr new_handles); | |
| 68 ScopedPlatformHandleVectorPtr TakeHandles(); | |
| 69 | |
| 70 private: | |
| 71 size_t size_; | |
| 72 char* data_; | |
| 73 Header* header_; | |
| 74 | |
| 75 #if defined(OS_WIN) | |
| 76 // On Windows, handles are serialized in the data buffer along with the | |
| 77 // rest of the payload. | |
| 78 PlatformHandle* handles_ = nullptr; | |
| 79 #else | |
| 80 ScopedPlatformHandleVectorPtr handle_vector_; | |
| 81 #endif | |
| 82 | |
| 83 DISALLOW_COPY_AND_ASSIGN(Message); | |
| 84 }; | |
| 85 | |
| 86 // Delegate methods are called from the I/O task runner with which the Channel | |
| 87 // was created (see Channel::Create). | |
| 88 class Delegate { | |
| 89 public: | |
| 90 virtual ~Delegate() {} | |
| 91 | |
| 92 // Notify of a received message. |payload| is not owned and must not be | |
| 93 // retained; it will be null if |payload_size| is 0. |handles| are | |
| 94 // transferred to the callee. | |
| 95 virtual void OnChannelMessage(const void* payload, | |
| 96 size_t payload_size, | |
| 97 ScopedPlatformHandleVectorPtr handles) = 0; | |
| 98 | |
| 99 // Notify that an error has occured and the Channel will cease operation. | |
| 100 virtual void OnChannelError() = 0; | |
| 101 }; | |
| 102 | |
| 103 // Creates a new Channel around a |platform_handle|, taking ownership of the | |
| 104 // handle. All I/O on the handle will be performed on |io_task_runner|. | |
| 105 // Note that ShutDown() MUST be called on the Channel some time before | |
| 106 // |delegate| is destroyed. | |
| 107 static scoped_refptr<Channel> Create( | |
| 108 Delegate* delegate, | |
| 109 ScopedPlatformHandle platform_handle, | |
| 110 scoped_refptr<base::TaskRunner> io_task_runner); | |
| 111 | |
| 112 // Request that the channel be shut down. This should always be called before | |
| 113 // releasing the last reference to a Channel to ensure that it's cleaned up | |
| 114 // on its I/O task runner's thread. | |
| 115 // | |
| 116 // Delegate methods will no longer be invoked after this call. | |
| 117 void ShutDown(); | |
|
Anand Mistry (off Chromium)
2016/01/28 02:26:24
It's not clear which threads these can be called o
| |
| 118 | |
| 119 // Begin processing I/O events. Delegate methods must only be invoked after | |
| 120 // this call. | |
| 121 virtual void Start() = 0; | |
| 122 | |
| 123 // Stop processing I/O events. | |
| 124 virtual void ShutDownImpl() = 0; | |
| 125 | |
| 126 // Queues an outgoing message on the Channel. This message will either | |
| 127 // eventually be written or will fail to write and trigger | |
| 128 // Delegate::OnChannelError. | |
| 129 virtual void Write(MessagePtr message) = 0; | |
| 130 | |
| 131 protected: | |
| 132 explicit Channel(Delegate* delegate); | |
| 133 virtual ~Channel(); | |
| 134 | |
| 135 // Called by the implementation when it wants somewhere to stick data. | |
| 136 // |*buffer_capacity| may be set by the caller to indicate the desired buffer | |
| 137 // size. If 0, a sane default size will be used instead. | |
| 138 // | |
| 139 // Returns the address of a buffer which can be written to, and indicates its | |
| 140 // actual capacity in |*buffer_capacity|. | |
| 141 char* GetReadBuffer(size_t* buffer_capacity); | |
| 142 | |
| 143 // Called by the implementation when new data is available in the read | |
| 144 // buffer. Returns false to indicate an error. Upon success, | |
| 145 // |*next_read_size_hint| will be set to a recommended size for the next | |
| 146 // read done by the implementation. | |
| 147 bool OnReadComplete(size_t bytes_read, size_t* next_read_size_hint); | |
| 148 | |
| 149 // Called by the implementation when something goes horribly wrong. It is NOT | |
| 150 // OK to call this synchronously from any public interface methods. | |
| 151 void OnError(); | |
| 152 | |
| 153 // Retrieves the set of platform handles read for a given message. |payload| | |
| 154 // and |payload_size| correspond to the full message body. Depending on | |
| 155 // the Channel implementation, this body may encode platform handles, or | |
| 156 // handles may be stored and managed elsewhere by the implementation. | |
| 157 // If |num_handles| handles cannot be returned, this must return null. | |
| 158 // The implementation may also adjust the values of |*payload| and/or | |
| 159 // |*payload_size| to hide handle data from the user. | |
| 160 virtual ScopedPlatformHandleVectorPtr GetReadPlatformHandles( | |
| 161 size_t num_handles, | |
| 162 void** payload, | |
| 163 size_t* payload_size) = 0; | |
| 164 | |
| 165 private: | |
| 166 friend class base::RefCountedThreadSafe<Channel>; | |
| 167 | |
| 168 class ReadBuffer; | |
| 169 | |
| 170 Delegate* delegate_; | |
| 171 const scoped_ptr<ReadBuffer> read_buffer_; | |
| 172 | |
| 173 DISALLOW_COPY_AND_ASSIGN(Channel); | |
| 174 }; | |
| 175 | |
| 176 } // namespace edk | |
| 177 } // namespace mojo | |
| 178 | |
| 179 #endif // MOJO_EDK_SYSTEM_CHANNEL_H_ | |
| OLD | NEW |