Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: mojo/edk/system/channel.h

Issue 2710193003: Adding a new message type to the Mojo channel. (Closed)
Patch Set: Fix Mac build. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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_
OLDNEW
« no previous file with comments | « mojo/edk/system/BUILD.gn ('k') | mojo/edk/system/channel.cc » ('j') | mojo/edk/system/channel.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698