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

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

Issue 1598223004: Revert of [mojo] Add CreateSharedBuffer method to Broker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: presubmits Created 4 years, 11 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
« no previous file with comments | « mojo/edk/system/child_broker_host.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/child_broker_host.h" 5 #include "mojo/edk/system/child_broker_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "mojo/edk/embedder/embedder_internal.h" 13 #include "mojo/edk/embedder/embedder_internal.h"
14 #include "mojo/edk/embedder/platform_channel_pair.h" 14 #include "mojo/edk/embedder/platform_channel_pair.h"
15 #include "mojo/edk/embedder/platform_shared_buffer.h"
16 #include "mojo/edk/embedder/platform_support.h"
17 #include "mojo/edk/system/broker_messages.h" 15 #include "mojo/edk/system/broker_messages.h"
18 #include "mojo/edk/system/broker_state.h" 16 #include "mojo/edk/system/broker_state.h"
19 #include "mojo/edk/system/configuration.h" 17 #include "mojo/edk/system/configuration.h"
20 #include "mojo/edk/system/core.h" 18 #include "mojo/edk/system/core.h"
21 #include "mojo/edk/system/platform_handle_dispatcher.h" 19 #include "mojo/edk/system/platform_handle_dispatcher.h"
22 20
23 #if defined(OS_POSIX)
24 #include <fcntl.h>
25 #include <sys/uio.h>
26
27 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
28 #endif
29
30 namespace mojo { 21 namespace mojo {
31 namespace edk { 22 namespace edk {
32 23
33 namespace { 24 namespace {
34 #if defined(OS_WIN) 25 #if defined(OS_WIN)
35 static const int kDefaultReadBufferSize = 256; 26 static const int kDefaultReadBufferSize = 256;
36 #endif 27 #endif
37 } 28 }
38 29
39 ChildBrokerHost::ChildBrokerHost(base::ProcessHandle child_process, 30 ChildBrokerHost::ChildBrokerHost(base::ProcessHandle child_process,
40 ScopedPlatformHandle pipe) 31 ScopedPlatformHandle pipe)
41 : process_id_(base::GetProcId(child_process)), 32 : process_id_(base::GetProcId(child_process)), child_channel_(nullptr) {
42 child_channel_(nullptr), 33 ScopedPlatformHandle parent_async_channel_handle;
43 num_bytes_read_(0) { 34 #if defined(OS_POSIX)
44 // First set up the synchronous pipe. 35 parent_async_channel_handle = std::move(pipe);
45 sync_channel_ = std::move(pipe); 36 #else
46
47 // See comment in ChildBroker::SetChildBrokerHostHandle. Summary is we need
48 // two pipes, so send the second one over the first one.
49 PlatformChannelPair parent_pipe;
50
51 ScopedPlatformHandle parent_async_channel_handle =
52 parent_pipe.PassServerHandle();
53
54 num_bytes_read_ = 0;
55
56 // Send over the async pipe.
57 #if defined(OS_WIN)
58 DuplicateHandle(GetCurrentProcess(), child_process, 37 DuplicateHandle(GetCurrentProcess(), child_process,
59 GetCurrentProcess(), &child_process, 38 GetCurrentProcess(), &child_process,
60 0, FALSE, DUPLICATE_SAME_ACCESS); 39 0, FALSE, DUPLICATE_SAME_ACCESS);
61 child_process_ = base::Process(child_process); 40 child_process_ = base::Process(child_process);
62 41 sync_channel_ = std::move(pipe);
63 memset(&read_context_.overlapped, 0, sizeof(read_context_.overlapped)); 42 memset(&read_context_.overlapped, 0, sizeof(read_context_.overlapped));
64 read_context_.handler = this; 43 read_context_.handler = this;
65 memset(&write_context_.overlapped, 0, sizeof(write_context_.overlapped)); 44 memset(&write_context_.overlapped, 0, sizeof(write_context_.overlapped));
66 write_context_.handler = this; 45 write_context_.handler = this;
67 read_data_.resize(kDefaultReadBufferSize); 46 read_data_.resize(kDefaultReadBufferSize);
47 num_bytes_read_ = 0;
48
49 // See comment in ChildBroker::SetChildBrokerHostHandle. Summary is we need
50 // two pipes on Windows, so send the second one over the first one.
51 PlatformChannelPair parent_pipe;
52 parent_async_channel_handle = parent_pipe.PassServerHandle();
68 53
69 HANDLE duplicated_child_handle = 54 HANDLE duplicated_child_handle =
70 DuplicateToChild(parent_pipe.PassClientHandle().release().handle); 55 DuplicateToChild(parent_pipe.PassClientHandle().release().handle);
71 BOOL rv = WriteFile(sync_channel_.get().handle, 56 BOOL rv = WriteFile(sync_channel_.get().handle,
72 &duplicated_child_handle, sizeof(duplicated_child_handle), 57 &duplicated_child_handle, sizeof(duplicated_child_handle),
73 NULL, &write_context_.overlapped); 58 NULL, &write_context_.overlapped);
74 DCHECK(rv || GetLastError() == ERROR_IO_PENDING); 59 DCHECK(rv || GetLastError() == ERROR_IO_PENDING);
75 #else
76 // Send just one null byte.
77 struct iovec iov = {const_cast<char*>(""), 1};
78 PlatformHandle child_handle = parent_pipe.PassClientHandle().release();
79 ssize_t result = PlatformChannelSendmsgWithHandles(sync_channel_.get(), &iov,
80 1, &child_handle, 1);
81 CHECK_NE(-1, result);
82 #endif 60 #endif
83 61
84 internal::g_io_thread_task_runner->PostTask( 62 internal::g_io_thread_task_runner->PostTask(
85 FROM_HERE, 63 FROM_HERE,
86 base::Bind(&ChildBrokerHost::InitOnIO, base::Unretained(this), 64 base::Bind(&ChildBrokerHost::InitOnIO, base::Unretained(this),
87 base::Passed(&parent_async_channel_handle))); 65 base::Passed(&parent_async_channel_handle)));
88 } 66 }
89 67
90 base::ProcessId ChildBrokerHost::GetProcessId() { 68 base::ProcessId ChildBrokerHost::GetProcessId() {
91 return process_id_; 69 return process_id_;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 134
157 BrokerState::GetInstance()->ChildBrokerHostCreated(this); 135 BrokerState::GetInstance()->ChildBrokerHostCreated(this);
158 136
159 #if defined(OS_WIN) 137 #if defined(OS_WIN)
160 // Call this after RoutedRawChannel calls its RawChannel::Init because this 138 // Call this after RoutedRawChannel calls its RawChannel::Init because this
161 // call could cause us to get notified that the child has gone away and to 139 // call could cause us to get notified that the child has gone away and to
162 // delete this class and shut down child_channel_ before Init() has run. 140 // delete this class and shut down child_channel_ before Init() has run.
163 base::MessageLoopForIO::current()->RegisterIOHandler( 141 base::MessageLoopForIO::current()->RegisterIOHandler(
164 sync_channel_.get().handle, this); 142 sync_channel_.get().handle, this);
165 BeginRead(); 143 BeginRead();
166 #else
167 base::MessageLoopForIO::current()->WatchFileDescriptor(
168 sync_channel_.get().handle, true, base::MessageLoopForIO::WATCH_READ,
169 &fd_controller_, this);
170 TryReadAndWriteHandles();
171 #endif 144 #endif
172 } 145 }
173 146
174 void ChildBrokerHost::OnReadMessage( 147 void ChildBrokerHost::OnReadMessage(
175 const MessageInTransit::View& message_view, 148 const MessageInTransit::View& message_view,
176 ScopedPlatformHandleVectorPtr platform_handles) { 149 ScopedPlatformHandleVectorPtr platform_handles) {
177 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 150 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
178 CHECK(!platform_handles); 151 CHECK(!platform_handles);
179 if (message_view.num_bytes() != 152 if (message_view.num_bytes() !=
180 static_cast<uint32_t>(sizeof(ConnectMessagePipeMessage))) { 153 static_cast<uint32_t>(sizeof(ConnectMessagePipeMessage))) {
(...skipping 18 matching lines...) Expand all
199 } 172 }
200 } 173 }
201 174
202 void ChildBrokerHost::OnError(Error error) { 175 void ChildBrokerHost::OnError(Error error) {
203 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 176 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
204 child_channel_->RemoveRoute(kBrokerRouteId); 177 child_channel_->RemoveRoute(kBrokerRouteId);
205 child_channel_ = nullptr; 178 child_channel_ = nullptr;
206 } 179 }
207 180
208 void ChildBrokerHost::ChannelDestructed(RoutedRawChannel* channel) { 181 void ChildBrokerHost::ChannelDestructed(RoutedRawChannel* channel) {
209 // We have two pipes to the child process. It's easier to wait 182 // On Windows, we have two pipes to the child process. It's easier to wait
210 // until we get the error from the pipe that is used for synchronous I/O. 183 // until we get the error from the pipe that is used for synchronous I/O.
184 #if !defined(OS_WIN)
185 delete this;
186 #endif
211 } 187 }
212 188
213 #if defined(OS_WIN) 189 #if defined(OS_WIN)
214 void ChildBrokerHost::BeginRead() { 190 void ChildBrokerHost::BeginRead() {
215 BOOL rv = ReadFile(sync_channel_.get().handle, 191 BOOL rv = ReadFile(sync_channel_.get().handle,
216 &read_data_[num_bytes_read_], 192 &read_data_[num_bytes_read_],
217 static_cast<int>(read_data_.size() - num_bytes_read_), 193 static_cast<int>(read_data_.size() - num_bytes_read_),
218 nullptr, &read_context_.overlapped); 194 nullptr, &read_context_.overlapped);
219 if (rv || GetLastError() == ERROR_IO_PENDING) 195 if (rv || GetLastError() == ERROR_IO_PENDING)
220 return; 196 return;
(...skipping 21 matching lines...) Expand all
242 return; 218 return;
243 } 219 }
244 220
245 if (context == &write_context_) { 221 if (context == &write_context_) {
246 write_data_.clear(); 222 write_data_.clear();
247 return; 223 return;
248 } 224 }
249 225
250 num_bytes_read_ += bytes_transferred; 226 num_bytes_read_ += bytes_transferred;
251 CHECK_GE(num_bytes_read_, sizeof(uint32_t)); 227 CHECK_GE(num_bytes_read_, sizeof(uint32_t));
252 BrokerMessage* message = reinterpret_cast<BrokerMessage*>(read_data_.data()); 228 BrokerMessage* message = reinterpret_cast<BrokerMessage*>(&read_data_[0]);
253 if (num_bytes_read_ < message->size) { 229 if (num_bytes_read_ < message->size) {
254 read_data_.resize(message->size); 230 read_data_.resize(message->size);
255 BeginRead(); 231 BeginRead();
256 return; 232 return;
257 } 233 }
258 234
259 // This should never fire because we only get new requests from a child 235 // This should never fire because we only get new requests from a child
260 // process after it has read all the previous data we wrote. 236 // process after it has read all the previous data we wrote.
261 if (!write_data_.empty()) { 237 if (!write_data_.empty()) {
262 NOTREACHED() << "ChildBrokerHost shouldn't have data to write when it gets " 238 NOTREACHED() << "ChildBrokerHost shouldn't have data to write when it gets "
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 } 316 }
341 317
342 HANDLE ChildBrokerHost::DuplicateFromChild(HANDLE handle) { 318 HANDLE ChildBrokerHost::DuplicateFromChild(HANDLE handle) {
343 HANDLE rv = INVALID_HANDLE_VALUE; 319 HANDLE rv = INVALID_HANDLE_VALUE;
344 BOOL result = DuplicateHandle(child_process_.Handle(), handle, 320 BOOL result = DuplicateHandle(child_process_.Handle(), handle,
345 base::GetCurrentProcessHandle(), &rv, 0, FALSE, 321 base::GetCurrentProcessHandle(), &rv, 0, FALSE,
346 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); 322 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
347 DCHECK(result); 323 DCHECK(result);
348 return rv; 324 return rv;
349 } 325 }
350 #else
351 void ChildBrokerHost::TryReadAndWriteHandles() {
352 // Message sizes are constant on POSIX currently. Further, the child process
353 // only writes one message before it gets a response.
354 read_data_.resize(sizeof(BrokerMessage));
355
356 std::deque<PlatformHandle> dummy;
357 ssize_t bytes_read = PlatformChannelRecvmsg(
358 sync_channel_.get(), &read_data_[num_bytes_read_],
359 static_cast<int>(read_data_.size() - num_bytes_read_), &dummy);
360 DCHECK(dummy.empty());
361
362 // We call TryReadAndWriteHandles when we are first initialized so this could
363 // fail with EAGAIN or EWOULDBLOCK.
364 if (bytes_read == 0 ||
365 (bytes_read == -1 && errno != EAGAIN && errno != EWOULDBLOCK)) {
366 delete this;
367 return;
368 }
369
370 if (bytes_read == -1)
371 return;
372
373 num_bytes_read_ += bytes_read;
374
375 // We don't know how big the message is yet.
376 if (num_bytes_read_ < sizeof(uint32_t))
377 return;
378
379 BrokerMessage* message = reinterpret_cast<BrokerMessage*>(read_data_.data());
380 // Message not fully read yet.
381 if (num_bytes_read_ < message->size) {
382 DCHECK_LE(message->size, sizeof(BrokerMessage));
383 return;
384 }
385
386 // Should only get one message.
387 DCHECK_EQ(num_bytes_read_, message->size);
388
389 PlatformHandle handle;
390 if (message->id == CREATE_SHARED_BUFFER) {
391 scoped_refptr<PlatformSharedBuffer> shared_buffer =
392 internal::g_platform_support->CreateSharedBuffer(
393 message->shared_buffer_size);
394 if (shared_buffer)
395 handle = shared_buffer->PassPlatformHandle().release();
396 else
397 LOG(ERROR) << "ChildBrokerHost failed to create shared buffer of size "
398 << message->shared_buffer_size;
399 } else {
400 NOTREACHED() << "Unknown command. Stopping reading.";
401 delete this;
402 return;
403 }
404
405 num_bytes_read_ = 0;
406 read_data_.clear();
407
408 // Send just one null byte. Also send back a null platform handle if we
409 // couldn't create the shared buffer.
410 struct iovec iov = {const_cast<char*>(""), 1};
411 ssize_t result = PlatformChannelSendmsgWithHandles(sync_channel_.get(), &iov,
412 1, &handle, 1);
413 if (result == -1) {
414 PLOG(ERROR) << "ChildBrokerHost could not write to peer";
415 delete this;
416 }
417 }
418
419 void ChildBrokerHost::OnFileCanReadWithoutBlocking(int fd) {
420 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
421 if (fd != sync_channel_.get().handle) {
422 NOTREACHED() << "ChildBrokerHost shouldn't get notifications about file "
423 "descriptors other than sync_channel_'s";
424 delete this;
425 return;
426 }
427
428 TryReadAndWriteHandles();
429 }
430
431 void ChildBrokerHost::OnFileCanWriteWithoutBlocking(int fd) {}
432 #endif 326 #endif
433 327
434 } // namespace edk 328 } // namespace edk
435 } // namespace mojo 329 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/child_broker_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698