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

Side by Side Diff: mojo/edk/system/message_pipe_dispatcher.cc

Issue 1387963004: Create a broker interface for the new Mojo EDK so that the browser can create and duplicate messa... (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: presubmit whitespace error Created 5 years 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 2015 The Chromium Authors. All rights reserved. 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 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 #include "mojo/edk/system/message_pipe_dispatcher.h" 5 #include "mojo/edk/system/message_pipe_dispatcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "mojo/edk/embedder/embedder_internal.h" 10 #include "mojo/edk/embedder/embedder_internal.h"
11 #include "mojo/edk/embedder/platform_handle_utils.h" 11 #include "mojo/edk/embedder/platform_handle_utils.h"
12 #include "mojo/edk/embedder/platform_shared_buffer.h" 12 #include "mojo/edk/embedder/platform_shared_buffer.h"
13 #include "mojo/edk/embedder/platform_support.h" 13 #include "mojo/edk/embedder/platform_support.h"
14 #include "mojo/edk/system/configuration.h" 14 #include "mojo/edk/system/configuration.h"
15 #include "mojo/edk/system/message_in_transit.h" 15 #include "mojo/edk/system/message_in_transit.h"
16 #include "mojo/edk/system/options_validation.h" 16 #include "mojo/edk/system/options_validation.h"
17 #include "mojo/edk/system/transport_data.h" 17 #include "mojo/edk/system/transport_data.h"
18 18
19 #if defined(OS_WIN)
20 #include "mojo/edk/system/token_serializer_win.h"
21 #endif
22
19 namespace mojo { 23 namespace mojo {
20 namespace edk { 24 namespace edk {
21 25
22 // TODO(jam): do more tests on using channel on same thread if it supports it ( 26 // TODO(jam): do more tests on using channel on same thread if it supports it (
23 // i.e. with USE_CHROME_EDK and Windows). Also see ipc_channel_mojo.cc 27 // i.e. with USE_CHROME_EDK and Windows). Also see ipc_channel_mojo.cc
24 bool g_use_channel_on_io_thread_only = true; 28 bool g_use_channel_on_io_thread_only = true;
25 29
26 namespace { 30 namespace {
27 31
28 const size_t kInvalidMessagePipeHandleIndex = static_cast<size_t>(-1); 32 const size_t kInvalidMessagePipeHandleIndex = static_cast<size_t>(-1);
29 33
30 struct MOJO_ALIGNAS(8) SerializedMessagePipeHandleDispatcher { 34 struct MOJO_ALIGNAS(8) SerializedMessagePipeHandleDispatcher {
31 // Could be |kInvalidMessagePipeHandleIndex| if the other endpoint of the MP 35 // Could be |kInvalidMessagePipeHandleIndex| if the other endpoint of the MP
32 // was closed. 36 // was closed.
33 size_t platform_handle_index; 37 size_t platform_handle_index;
34 bool write_error; 38 bool write_error;
35 39
36 size_t shared_memory_handle_index; // (Or |kInvalidMessagePipeHandleIndex|.) 40 size_t shared_memory_handle_index; // (Or |kInvalidMessagePipeHandleIndex|.)
37 uint32_t shared_memory_size; 41 uint32_t shared_memory_size;
38 42
39 size_t serialized_read_buffer_size; 43 size_t serialized_read_buffer_size;
40 size_t serialized_write_buffer_size; 44 size_t serialized_write_buffer_size;
41 size_t serialized_messagage_queue_size; 45 size_t serialized_message_queue_size;
42 46
43 // These are the FDs required as part of serializing channel_ and 47 // These are the FDs required as part of serializing channel_ and
44 // message_queue_. This is only used on POSIX. 48 // message_queue_. This is only used on POSIX.
45 size_t serialized_fds_index; // (Or |kInvalidMessagePipeHandleIndex|.) 49 size_t serialized_fds_index; // (Or |kInvalidMessagePipeHandleIndex|.)
46 size_t serialized_read_fds_length; 50 size_t serialized_read_fds_length;
47 size_t serialized_write_fds_length; 51 size_t serialized_write_fds_length;
48 size_t serialized_message_fds_length; 52 size_t serialized_message_fds_length;
49 }; 53 };
50 54
51 char* SerializeBuffer(char* start, std::vector<char>* buffer) { 55 char* SerializeBuffer(char* start, std::vector<char>* buffer) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 if (channel_) { 158 if (channel_) {
155 channel_->Shutdown(); 159 channel_->Shutdown();
156 channel_ = nullptr; 160 channel_ = nullptr;
157 } 161 }
158 } 162 }
159 163
160 Dispatcher::Type MessagePipeDispatcher::GetType() const { 164 Dispatcher::Type MessagePipeDispatcher::GetType() const {
161 return Type::MESSAGE_PIPE; 165 return Type::MESSAGE_PIPE;
162 } 166 }
163 167
168 #if defined(OS_WIN)
164 // TODO(jam): this is copied from RawChannelWin till I figure out what's the 169 // TODO(jam): this is copied from RawChannelWin till I figure out what's the
165 // best way we want to share this. Need to also consider posix which does 170 // best way we want to share this.
166 // require access to the RawChannel.
167 // Since this is used for serialization of messages read/written to a MP that 171 // Since this is used for serialization of messages read/written to a MP that
168 // aren't consumed by Mojo primitives yet, there could be an unbounded number of 172 // aren't consumed by Mojo primitives yet, there could be an unbounded number of
169 // them when a MP is being sent. As a result, even for POSIX we will probably 173 // them when a MP is being sent. As a result, even for POSIX we will probably
170 // want to send the handles to the shell process and exchange them for tokens 174 // want to send the handles to the shell process and exchange them for tokens
171 // (since we can be sure that the shell will respond to our IPCs, compared to 175 // (since we can be sure that the shell will respond to our IPCs, compared to
172 // the other end where we're sending the MP to, which may not be reading...). 176 // the other end where we're sending the MP to, which may not be reading...).
173 ScopedPlatformHandleVectorPtr GetReadPlatformHandles( 177 ScopedPlatformHandleVectorPtr GetReadPlatformHandles(
174 size_t num_platform_handles, 178 size_t num_platform_handles,
175 const void* platform_handle_table) { 179 const void* platform_handle_table) {
176 // TODO(jam): this code will have to be updated once it's used in a sandbox
177 // and the receiving process doesn't have duplicate permission for the
178 // receiver. Once there's a broker and we have a connection to it (possibly
179 // through ConnectionManager), then we can make a sync IPC to it here to get a
180 // token for this handle, and it will duplicate the handle to is process. Then
181 // we pass the token to the receiver, which will then make a sync call to the
182 // broker to get a duplicated handle. This will also allow us to avoid leaks
183 // of the handle if the receiver dies, since the broker can notice that.
184 DCHECK_GT(num_platform_handles, 0u);
185 ScopedPlatformHandleVectorPtr rv(new PlatformHandleVector()); 180 ScopedPlatformHandleVectorPtr rv(new PlatformHandleVector());
181 rv->resize(num_platform_handles);
186 182
187 #if defined(OS_WIN) 183 const uint64_t* tokens =
188 const char* serialization_data = 184 static_cast<const uint64_t*>(platform_handle_table);
189 static_cast<const char*>(platform_handle_table); 185 internal::g_token_serializer->TokenToHandle(
190 for (size_t i = 0; i < num_platform_handles; i++) { 186 tokens, num_platform_handles, &rv->at(0));
191 DWORD pid = *reinterpret_cast<const DWORD*>(serialization_data);
192 serialization_data += sizeof(DWORD);
193 HANDLE source_handle = *reinterpret_cast<const HANDLE*>(serialization_data);
194 serialization_data += sizeof(HANDLE);
195 base::Process sender =
196 base::Process::OpenWithAccess(pid, PROCESS_DUP_HANDLE);
197 DCHECK(sender.IsValid());
198 HANDLE target_handle = NULL;
199 BOOL dup_result =
200 DuplicateHandle(sender.Handle(), source_handle,
201 base::GetCurrentProcessHandle(), &target_handle, 0,
202 FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
203 DCHECK(dup_result);
204 rv->push_back(PlatformHandle(target_handle));
205 }
206 #else
207 NOTREACHED() << "TODO(jam): implement";
208 #endif
209 return rv.Pass(); 187 return rv.Pass();
210 } 188 }
189 #endif
211 190
212 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( 191 scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize(
213 const void* source, 192 const void* source,
214 size_t size, 193 size_t size,
215 PlatformHandleVector* platform_handles) { 194 PlatformHandleVector* platform_handles) {
216 if (size != sizeof(SerializedMessagePipeHandleDispatcher)) { 195 if (size != sizeof(SerializedMessagePipeHandleDispatcher)) {
217 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad size)"; 196 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad size)";
218 return nullptr; 197 return nullptr;
219 } 198 }
220 199
221 const SerializedMessagePipeHandleDispatcher* serialization = 200 const SerializedMessagePipeHandleDispatcher* serialization =
222 static_cast<const SerializedMessagePipeHandleDispatcher*>(source); 201 static_cast<const SerializedMessagePipeHandleDispatcher*>(source);
223 if (serialization->shared_memory_size != 202 if (serialization->shared_memory_size !=
224 (serialization->serialized_read_buffer_size + 203 (serialization->serialized_read_buffer_size +
225 serialization->serialized_write_buffer_size + 204 serialization->serialized_write_buffer_size +
226 serialization->serialized_messagage_queue_size)) { 205 serialization->serialized_message_queue_size)) {
227 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad struct)"; 206 LOG(ERROR) << "Invalid serialized message pipe dispatcher (bad struct)";
228 return nullptr; 207 return nullptr;
229 } 208 }
230 209
231 ScopedPlatformHandle platform_handle, shared_memory_handle; 210 ScopedPlatformHandle platform_handle, shared_memory_handle;
232 if (!GetHandle(serialization->platform_handle_index, 211 if (!GetHandle(serialization->platform_handle_index,
233 platform_handles, &platform_handle) || 212 platform_handles, &platform_handle) ||
234 !GetHandle(serialization->shared_memory_handle_index, 213 !GetHandle(serialization->shared_memory_handle_index,
235 platform_handles, &shared_memory_handle)) { 214 platform_handles, &shared_memory_handle)) {
236 return nullptr; 215 return nullptr;
(...skipping 16 matching lines...) Expand all
253 serialized_read_buffer = buffer; 232 serialized_read_buffer = buffer;
254 serialized_read_buffer_size = serialization->serialized_read_buffer_size; 233 serialized_read_buffer_size = serialization->serialized_read_buffer_size;
255 buffer += serialized_read_buffer_size; 234 buffer += serialized_read_buffer_size;
256 } 235 }
257 if (serialization->serialized_write_buffer_size) { 236 if (serialization->serialized_write_buffer_size) {
258 serialized_write_buffer = buffer; 237 serialized_write_buffer = buffer;
259 serialized_write_buffer_size = 238 serialized_write_buffer_size =
260 serialization->serialized_write_buffer_size; 239 serialization->serialized_write_buffer_size;
261 buffer += serialized_write_buffer_size; 240 buffer += serialized_write_buffer_size;
262 } 241 }
263 if (serialization->serialized_messagage_queue_size) { 242 if (serialization->serialized_message_queue_size) {
264 message_queue_data = buffer; 243 message_queue_data = buffer;
265 message_queue_size = serialization->serialized_messagage_queue_size; 244 message_queue_size = serialization->serialized_message_queue_size;
266 buffer += message_queue_size; 245 buffer += message_queue_size;
267 } 246 }
268 } 247 }
269 248
270 scoped_refptr<MessagePipeDispatcher> rv( 249 scoped_refptr<MessagePipeDispatcher> rv(
271 Create(MessagePipeDispatcher::kDefaultCreateOptions)); 250 Create(MessagePipeDispatcher::kDefaultCreateOptions));
272 rv->write_error_ = serialization->write_error; 251 rv->write_error_ = serialization->write_error;
273 252
274 std::vector<int> serialized_read_fds; 253 std::vector<int> serialized_read_fds;
275 std::vector<int> serialized_write_fds; 254 std::vector<int> serialized_write_fds;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 static_cast<const char*>(message->main_buffer()), 431 static_cast<const char*>(message->main_buffer()),
453 static_cast<const char*>(message->main_buffer()) + main_buffer_size); 432 static_cast<const char*>(message->main_buffer()) + main_buffer_size);
454 433
455 // cont'd 434 // cont'd
456 if (transport_data_buffer_size != 0) { 435 if (transport_data_buffer_size != 0) {
457 // TODO(jam): copied from RawChannelWin::WriteNoLock( 436 // TODO(jam): copied from RawChannelWin::WriteNoLock(
458 PlatformHandleVector* all_platform_handles = 437 PlatformHandleVector* all_platform_handles =
459 message->transport_data()->platform_handles(); 438 message->transport_data()->platform_handles();
460 if (all_platform_handles) { 439 if (all_platform_handles) {
461 #if defined(OS_WIN) 440 #if defined(OS_WIN)
462 char* serialization_data = 441 uint64_t* tokens = reinterpret_cast<uint64_t*>(
463 static_cast<char*>(message->transport_data()->buffer()) + 442 static_cast<char*>(message->transport_data()->buffer()) +
464 message->transport_data()->platform_handle_table_offset(); 443 message->transport_data()->platform_handle_table_offset());
465 DWORD current_process_id = base::GetCurrentProcId(); 444 internal::g_token_serializer->HandleToToken(
466 for (size_t i = 0; i < all_platform_handles->size(); i++) { 445 &all_platform_handles->at(0), all_platform_handles->size(), tokens);
467 *reinterpret_cast<DWORD*>(serialization_data) = current_process_id; 446 for (size_t i = 0; i < all_platform_handles->size(); i++)
468 serialization_data += sizeof(DWORD);
469 *reinterpret_cast<HANDLE*>(serialization_data) =
470 all_platform_handles->at(i).handle;
471 serialization_data += sizeof(HANDLE);
472 all_platform_handles->at(i) = PlatformHandle(); 447 all_platform_handles->at(i) = PlatformHandle();
473 }
474 #else 448 #else
475 for (size_t i = 0; i < all_platform_handles->size(); i++) { 449 for (size_t i = 0; i < all_platform_handles->size(); i++) {
476 serialized_fds_.push_back(all_platform_handles->at(i).fd); 450 serialized_fds_.push_back(all_platform_handles->at(i).fd);
477 serialized_message_fds_length_++; 451 serialized_message_fds_length_++;
478 all_platform_handles->at(i) = PlatformHandle(); 452 all_platform_handles->at(i) = PlatformHandle();
479 } 453 }
480 #endif 454 #endif
481 455
482 serialized_message_queue_.insert( 456 serialized_message_queue_.insert(
483 serialized_message_queue_.end(), 457 serialized_message_queue_.end(),
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 if (serialized_platform_handle_.is_valid()) { 667 if (serialized_platform_handle_.is_valid()) {
694 serialization->platform_handle_index = platform_handles->size(); 668 serialization->platform_handle_index = platform_handles->size();
695 platform_handles->push_back(serialized_platform_handle_.release()); 669 platform_handles->push_back(serialized_platform_handle_.release());
696 } else { 670 } else {
697 serialization->platform_handle_index = kInvalidMessagePipeHandleIndex; 671 serialization->platform_handle_index = kInvalidMessagePipeHandleIndex;
698 } 672 }
699 673
700 serialization->write_error = write_error_; 674 serialization->write_error = write_error_;
701 serialization->serialized_read_buffer_size = serialized_read_buffer_.size(); 675 serialization->serialized_read_buffer_size = serialized_read_buffer_.size();
702 serialization->serialized_write_buffer_size = serialized_write_buffer_.size(); 676 serialization->serialized_write_buffer_size = serialized_write_buffer_.size();
703 serialization->serialized_messagage_queue_size = 677 serialization->serialized_message_queue_size =
704 serialized_message_queue_.size(); 678 serialized_message_queue_.size();
705 679
706 serialization->shared_memory_size = static_cast<uint32_t>( 680 serialization->shared_memory_size = static_cast<uint32_t>(
707 serialization->serialized_read_buffer_size + 681 serialization->serialized_read_buffer_size +
708 serialization->serialized_write_buffer_size + 682 serialization->serialized_write_buffer_size +
709 serialization->serialized_messagage_queue_size); 683 serialization->serialized_message_queue_size);
710 if (serialization->shared_memory_size) { 684 if (serialization->shared_memory_size) {
711 scoped_refptr<PlatformSharedBuffer> shared_buffer( 685 scoped_refptr<PlatformSharedBuffer> shared_buffer(
712 internal::g_platform_support->CreateSharedBuffer( 686 internal::g_platform_support->CreateSharedBuffer(
713 serialization->shared_memory_size)); 687 serialization->shared_memory_size));
714 scoped_ptr<PlatformSharedBufferMapping> mapping( 688 scoped_ptr<PlatformSharedBufferMapping> mapping(
715 shared_buffer->Map(0, serialization->shared_memory_size)); 689 shared_buffer->Map(0, serialization->shared_memory_size));
716 char* start = static_cast<char*>(mapping->GetBase()); 690 char* start = static_cast<char*>(mapping->GetBase());
717 start = SerializeBuffer(start, &serialized_read_buffer_); 691 start = SerializeBuffer(start, &serialized_read_buffer_);
718 start = SerializeBuffer(start, &serialized_write_buffer_); 692 start = SerializeBuffer(start, &serialized_write_buffer_);
719 start = SerializeBuffer(start, &serialized_message_queue_); 693 start = SerializeBuffer(start, &serialized_message_queue_);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 LOG(WARNING) << "Enqueueing null dispatcher"; 855 LOG(WARNING) << "Enqueueing null dispatcher";
882 dispatchers->push_back(nullptr); 856 dispatchers->push_back(nullptr);
883 } 857 }
884 } 858 }
885 message->SetDispatchers(dispatchers.Pass()); 859 message->SetDispatchers(dispatchers.Pass());
886 return MOJO_RESULT_OK; 860 return MOJO_RESULT_OK;
887 } 861 }
888 862
889 } // namespace edk 863 } // namespace edk
890 } // namespace mojo 864 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698