Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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_CHANNEL_H_ | 5 #ifndef MOJO_EDK_SYSTEM_CHANNEL_H_ |
| 6 #define MOJO_EDK_SYSTEM_CHANNEL_H_ | 6 #define MOJO_EDK_SYSTEM_CHANNEL_H_ |
| 7 | 7 |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/process/process_handle.h" | 11 #include "base/process/process_handle.h" |
| 12 #include "base/task_runner.h" | 12 #include "base/task_runner.h" |
| 13 #include "mojo/edk/embedder/platform_handle_vector.h" | 13 #include "mojo/edk/embedder/platform_handle_vector.h" |
| 14 #include "mojo/edk/embedder/scoped_platform_handle.h" | 14 #include "mojo/edk/embedder/scoped_platform_handle.h" |
| 15 | 15 |
| 16 namespace mojo { | 16 namespace mojo { |
| 17 namespace edk { | 17 namespace edk { |
| 18 | 18 |
| 19 const size_t kChannelMessageAlignment = 8; | 19 const size_t kChannelMessageAlignment = 8; |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
nit: We could also now add a utility like:
conste
Jay Civelli
2017/02/27 17:07:03
Good idea, done.
| |
| 20 | 20 |
| 21 // Channel provides a thread-safe interface to read and write arbitrary | 21 // Channel provides a thread-safe interface to read and write arbitrary |
| 22 // delimited messages over an underlying I/O channel, optionally transferring | 22 // delimited messages over an underlying I/O channel, optionally transferring |
| 23 // one or more platform handles in the process. | 23 // one or more platform handles in the process. |
| 24 class Channel : public base::RefCountedThreadSafe<Channel> { | 24 class MOJO_SYSTEM_IMPL_EXPORT Channel |
| 25 : public base::RefCountedThreadSafe<Channel> { | |
| 25 public: | 26 public: |
| 26 struct Message; | 27 struct Message; |
| 27 | 28 |
| 28 using MessagePtr = std::unique_ptr<Message>; | 29 using MessagePtr = std::unique_ptr<Message>; |
| 29 | 30 |
| 30 // A message to be written to a channel. | 31 // A message to be written to a channel. |
| 31 struct Message { | 32 struct Message { |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
You also need an EXPORT macro on the nested types
Jay Civelli
2017/02/27 17:07:03
Yes, that's the only other one used in the test I
| |
| 33 enum class MessageType : uint16_t { | |
| 34 // A normal message. | |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
nit: update comment?
Jay Civelli
2017/02/27 17:07:03
Done.
| |
| 35 NORMAL_LEGACY = 0, | |
| 36 #if defined(OS_MACOSX) | |
| 37 // A control message containing handles to echo back. | |
| 38 HANDLES_SENT, | |
| 39 // A control message containing handles that can now be closed. | |
| 40 HANDLES_SENT_ACK, | |
| 41 #endif | |
| 42 NORMAL_VERSIONED, | |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
nit: NORMAL is probably fine if we call the old on
Jay Civelli
2017/02/27 17:07:03
Done.
| |
| 43 }; | |
| 44 | |
| 32 #pragma pack(push, 1) | 45 #pragma pack(push, 1) |
| 33 struct Header { | 46 // Old message wire format for ChromeOS and Android, used by NORMAL_LEGACY |
| 34 enum class MessageType : uint16_t { | 47 // messages. |
| 35 // A normal message. | 48 // TODO: Remove once Arc++ uses versioned messages. |
| 36 NORMAL = 0, | 49 struct LegacyHeader { |
| 37 #if defined(OS_MACOSX) | |
| 38 // A control message containing handles to echo back. | |
| 39 HANDLES_SENT, | |
| 40 // A control message containing handles that can now be closed. | |
| 41 HANDLES_SENT_ACK, | |
| 42 #endif | |
| 43 }; | |
| 44 | |
| 45 // Message size in bytes, including the header. | 50 // Message size in bytes, including the header. |
| 46 uint32_t num_bytes; | 51 uint32_t num_bytes; |
| 47 | 52 |
| 48 #if defined(MOJO_EDK_LEGACY_PROTOCOL) | |
| 49 // Old message wire format for ChromeOS and Android. | |
| 50 // Number of attached handles. | 53 // Number of attached handles. |
| 51 uint16_t num_handles; | 54 uint16_t num_handles; |
| 52 | 55 |
| 53 MessageType message_type; | 56 MessageType message_type; |
| 54 #else | 57 }; |
| 58 | |
| 59 // Header used by NORMAL_VERSIONED messages. | |
| 60 // To preserve backward compatibility with LegacyHeader, the num_bytes and | |
| 61 // message_type field should be at the same offset than in LegacyHeader. | |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
nit: s/should be/must be/
Also please add a notic
Jay Civelli
2017/02/27 17:07:03
Done.
| |
| 62 struct VersionedHeader { | |
| 63 // Message size in bytes, including the header. | |
| 64 uint32_t num_bytes; | |
| 65 | |
| 55 // Total size of header, including extra header data (i.e. HANDLEs on | 66 // Total size of header, including extra header data (i.e. HANDLEs on |
| 56 // windows). | 67 // windows). |
| 57 uint16_t num_header_bytes; | 68 uint16_t num_header_bytes; |
| 58 | 69 |
| 70 MessageType message_type; | |
| 71 | |
| 72 uint16_t version_number; | |
| 73 | |
| 59 // Number of attached handles. May be less than the reserved handle | 74 // Number of attached handles. May be less than the reserved handle |
| 60 // storage size in this message on platforms that serialise handles as | 75 // storage size in this message on platforms that serialise handles as |
| 61 // data (i.e. HANDLEs on Windows, Mach ports on OSX). | 76 // data (i.e. HANDLEs on Windows, Mach ports on OSX). |
| 62 uint16_t num_handles; | 77 uint16_t num_handles; |
| 63 | 78 |
| 64 MessageType message_type; | 79 char padding[4]; |
| 65 | |
| 66 char padding[6]; | |
| 67 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL) | |
| 68 }; | 80 }; |
| 69 | 81 |
| 70 #if defined(OS_MACOSX) && !defined(OS_IOS) | 82 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 71 struct MachPortsEntry { | 83 struct MachPortsEntry { |
| 72 // Index of Mach port in the original vector of PlatformHandles. | 84 // Index of Mach port in the original vector of PlatformHandles. |
| 73 uint16_t index; | 85 uint16_t index; |
| 74 | 86 |
| 75 // Mach port name. | 87 // Mach port name. |
| 76 uint32_t mach_port; | 88 uint32_t mach_port; |
| 77 static_assert(sizeof(mach_port_t) <= sizeof(uint32_t), | 89 static_assert(sizeof(mach_port_t) <= sizeof(uint32_t), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 99 }; | 111 }; |
| 100 static_assert(sizeof(HandleEntry) == 4, | 112 static_assert(sizeof(HandleEntry) == 4, |
| 101 "sizeof(HandleEntry) must be 4 bytes"); | 113 "sizeof(HandleEntry) must be 4 bytes"); |
| 102 #endif | 114 #endif |
| 103 #pragma pack(pop) | 115 #pragma pack(pop) |
| 104 | 116 |
| 105 // Allocates and owns a buffer for message data with enough capacity for | 117 // Allocates and owns a buffer for message data with enough capacity for |
| 106 // |payload_size| bytes plus a header, plus |max_handles| platform handles. | 118 // |payload_size| bytes plus a header, plus |max_handles| platform handles. |
| 107 Message(size_t payload_size, | 119 Message(size_t payload_size, |
| 108 size_t max_handles, | 120 size_t max_handles, |
| 109 Header::MessageType message_type = Header::MessageType::NORMAL); | 121 MessageType message_type = MessageType::NORMAL_LEGACY); |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
nit: I'd prefer to use a delegating constructor ra
Jay Civelli
2017/02/27 17:07:03
Done.
| |
| 110 | 122 |
| 111 ~Message(); | 123 ~Message(); |
| 112 | 124 |
| 113 // Constructs a Message from serialized message data. | 125 // Constructs a Message from serialized message data. |
| 114 static MessagePtr Deserialize(const void* data, size_t data_num_bytes); | 126 static MessagePtr Deserialize(const void* data, size_t data_num_bytes); |
| 115 | 127 |
| 116 const void* data() const { return data_; } | 128 const void* data() const { return data_; } |
| 117 size_t data_num_bytes() const { return size_; } | 129 size_t data_num_bytes() const { return size_; } |
| 118 | 130 |
| 119 #if defined(MOJO_EDK_LEGACY_PROTOCOL) | 131 const void* extra_header() const; |
| 120 void* mutable_payload() { return static_cast<void*>(header_ + 1); } | 132 void* mutable_extra_header(); |
| 121 const void* payload() const { | 133 size_t extra_header_size() const; |
| 122 return static_cast<const void*>(header_ + 1); | 134 |
| 123 } | 135 void* mutable_payload(); |
| 136 const void* payload() const; | |
| 124 size_t payload_size() const; | 137 size_t payload_size() const; |
| 125 #else | |
| 126 const void* extra_header() const { return data_ + sizeof(Header); } | |
| 127 void* mutable_extra_header() { return data_ + sizeof(Header); } | |
| 128 size_t extra_header_size() const { | |
| 129 return header_->num_header_bytes - sizeof(Header); | |
| 130 } | |
| 131 | 138 |
| 132 void* mutable_payload() { return data_ + header_->num_header_bytes; } | 139 size_t num_handles() const; |
| 133 const void* payload() const { return data_ + header_->num_header_bytes; } | 140 bool has_handles() const; |
| 134 size_t payload_size() const; | |
| 135 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL) | |
| 136 | |
| 137 size_t num_handles() const { return header_->num_handles; } | |
| 138 bool has_handles() const { return header_->num_handles > 0; } | |
| 139 #if defined(OS_MACOSX) && !defined(OS_IOS) | 141 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 140 bool has_mach_ports() const; | 142 bool has_mach_ports() const; |
| 141 #endif | 143 #endif |
| 142 | 144 |
| 143 // Note: SetHandles() and TakeHandles() invalidate any previous value of | 145 // Note: SetHandles() and TakeHandles() invalidate any previous value of |
| 144 // handles(). | 146 // handles(). |
| 145 void SetHandles(ScopedPlatformHandleVectorPtr new_handles); | 147 void SetHandles(ScopedPlatformHandleVectorPtr new_handles); |
| 146 ScopedPlatformHandleVectorPtr TakeHandles(); | 148 ScopedPlatformHandleVectorPtr TakeHandles(); |
| 147 // Version of TakeHandles that returns a vector of platform handles suitable | 149 // Version of TakeHandles that returns a vector of platform handles suitable |
| 148 // for transfer over an underlying OS mechanism. i.e. file descriptors over | 150 // for transfer over an underlying OS mechanism. i.e. file descriptors over |
| 149 // a unix domain socket. Any handle that cannot be transferred this way, | 151 // a unix domain socket. Any handle that cannot be transferred this way, |
| 150 // such as Mach ports, will be removed. | 152 // such as Mach ports, will be removed. |
| 151 ScopedPlatformHandleVectorPtr TakeHandlesForTransport(); | 153 ScopedPlatformHandleVectorPtr TakeHandlesForTransport(); |
| 152 | 154 |
| 153 #if defined(OS_WIN) | 155 #if defined(OS_WIN) |
| 154 // Prepares the handles in this message for use in a different process. | 156 // Prepares the handles in this message for use in a different process. |
| 155 // Upon calling this the handles should belong to |from_process|; after the | 157 // Upon calling this the handles should belong to |from_process|; after the |
| 156 // call they'll belong to |to_process|. The source handles are always | 158 // call they'll belong to |to_process|. The source handles are always |
| 157 // closed by this call. Returns false iff one or more handles failed | 159 // closed by this call. Returns false iff one or more handles failed |
| 158 // duplication. | 160 // duplication. |
| 159 static bool RewriteHandles(base::ProcessHandle from_process, | 161 static bool RewriteHandles(base::ProcessHandle from_process, |
| 160 base::ProcessHandle to_process, | 162 base::ProcessHandle to_process, |
| 161 PlatformHandleVector* handles); | 163 PlatformHandleVector* handles); |
| 162 #endif | 164 #endif |
| 163 | 165 |
| 166 void SetVersionForTest(uint16_t version_number); | |
| 167 | |
| 164 private: | 168 private: |
| 165 size_t size_; | 169 size_t size_; |
| 166 size_t max_handles_; | 170 size_t max_handles_; |
| 167 char* data_; | 171 char* data_; |
| 168 Header* header_; | 172 LegacyHeader* legacy_header_ = nullptr; |
|
Ken Rockot(use gerrit already)
2017/02/23 22:07:05
nit: use an anonymous union for legacy_header_ and
Jay Civelli
2017/02/27 17:07:03
I use the fact that versioned_header_ is not null
| |
| 173 VersionedHeader* versioned_header_ = nullptr; | |
| 169 | 174 |
| 170 ScopedPlatformHandleVectorPtr handle_vector_; | 175 ScopedPlatformHandleVectorPtr handle_vector_; |
| 171 | 176 |
| 172 #if defined(OS_WIN) | 177 #if defined(OS_WIN) |
| 173 // On Windows, handles are serialised into the extra header section. | 178 // On Windows, handles are serialised into the extra header section. |
| 174 HandleEntry* handles_ = nullptr; | 179 HandleEntry* handles_ = nullptr; |
| 175 #elif defined(OS_MACOSX) && !defined(OS_IOS) | 180 #elif defined(OS_MACOSX) && !defined(OS_IOS) |
| 176 // On OSX, handles are serialised into the extra header section. | 181 // On OSX, handles are serialised into the extra header section. |
| 177 MachPortsExtraHeader* mach_ports_header_ = nullptr; | 182 MachPortsExtraHeader* mach_ports_header_ = nullptr; |
| 178 #endif | 183 #endif |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 // this is not necessarily an error condition. In such cases this returns | 268 // this is not necessarily an error condition. In such cases this returns |
| 264 // |true| but |*handles| will also be reset to null. | 269 // |true| but |*handles| will also be reset to null. |
| 265 virtual bool GetReadPlatformHandles( | 270 virtual bool GetReadPlatformHandles( |
| 266 size_t num_handles, | 271 size_t num_handles, |
| 267 const void* extra_header, | 272 const void* extra_header, |
| 268 size_t extra_header_size, | 273 size_t extra_header_size, |
| 269 ScopedPlatformHandleVectorPtr* handles) = 0; | 274 ScopedPlatformHandleVectorPtr* handles) = 0; |
| 270 | 275 |
| 271 // Handles a received control message. Returns |true| if the message is | 276 // Handles a received control message. Returns |true| if the message is |
| 272 // accepted, or |false| otherwise. | 277 // accepted, or |false| otherwise. |
| 273 virtual bool OnControlMessage(Message::Header::MessageType message_type, | 278 virtual bool OnControlMessage(Message::MessageType message_type, |
| 274 const void* payload, | 279 const void* payload, |
| 275 size_t payload_size, | 280 size_t payload_size, |
| 276 ScopedPlatformHandleVectorPtr handles); | 281 ScopedPlatformHandleVectorPtr handles); |
| 277 | 282 |
| 278 private: | 283 private: |
| 279 friend class base::RefCountedThreadSafe<Channel>; | 284 friend class base::RefCountedThreadSafe<Channel>; |
| 280 | 285 |
| 281 class ReadBuffer; | 286 class ReadBuffer; |
| 282 | 287 |
| 283 Delegate* delegate_; | 288 Delegate* delegate_; |
| 284 const std::unique_ptr<ReadBuffer> read_buffer_; | 289 const std::unique_ptr<ReadBuffer> read_buffer_; |
| 285 | 290 |
| 286 DISALLOW_COPY_AND_ASSIGN(Channel); | 291 DISALLOW_COPY_AND_ASSIGN(Channel); |
| 287 }; | 292 }; |
| 288 | 293 |
| 289 } // namespace edk | 294 } // namespace edk |
| 290 } // namespace mojo | 295 } // namespace mojo |
| 291 | 296 |
| 292 #endif // MOJO_EDK_SYSTEM_CHANNEL_H_ | 297 #endif // MOJO_EDK_SYSTEM_CHANNEL_H_ |
| OLD | NEW |