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

Side by Side Diff: mojo/edk/system/child_broker.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.h ('k') | mojo/edk/system/child_broker_host.h » ('j') | 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.h" 5 #include "mojo/edk/system/child_broker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "mojo/edk/embedder/embedder_internal.h" 14 #include "mojo/edk/embedder/embedder_internal.h"
15 #include "mojo/edk/embedder/platform_channel_pair.h" 15 #include "mojo/edk/embedder/platform_channel_pair.h"
16 #include "mojo/edk/embedder/platform_shared_buffer.h"
17 #include "mojo/edk/embedder/platform_support.h"
18 #include "mojo/edk/system/broker_messages.h" 16 #include "mojo/edk/system/broker_messages.h"
19 #include "mojo/edk/system/message_pipe_dispatcher.h" 17 #include "mojo/edk/system/message_pipe_dispatcher.h"
20 18
21 #if defined(OS_POSIX)
22 #include <fcntl.h>
23
24 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
25 #endif
26
27 namespace mojo { 19 namespace mojo {
28 namespace edk { 20 namespace edk {
29 21
30 ChildBroker* ChildBroker::GetInstance() { 22 ChildBroker* ChildBroker::GetInstance() {
31 return base::Singleton< 23 return base::Singleton<
32 ChildBroker, base::LeakySingletonTraits<ChildBroker>>::get(); 24 ChildBroker, base::LeakySingletonTraits<ChildBroker>>::get();
33 } 25 }
34 26
35 void ChildBroker::SetChildBrokerHostHandle(ScopedPlatformHandle handle) { 27 void ChildBroker::SetChildBrokerHostHandle(ScopedPlatformHandle handle) {
36 ScopedPlatformHandle parent_async_channel_handle; 28 ScopedPlatformHandle parent_async_channel_handle;
29 #if defined(OS_POSIX)
30 parent_async_channel_handle = std::move(handle);
31 #else
32 // On Windows we have two pipes to the parent. The first is for the token
33 // exchange for creating and passing handles, since the child needs the
34 // parent's help if it is sandboxed. The second is the same as POSIX, which is
35 // used for multiplexing related messages. So on Windows, we send the second
36 // pipe as the first string over the first one.
37 parent_sync_channel_ = std::move(handle); 37 parent_sync_channel_ = std::move(handle);
38 38
39 // We have two pipes to the parent. The first is for the token
40 // exchange for creating and passing handles on Windows, and creating shared
41 // buffers on POSIX, since the child needs the parent's help if it is
42 // sandboxed. The second is used for multiplexing related messages. We
43 // send the second over the first.
44 #if defined(OS_POSIX)
45 // Make the synchronous channel blocking.
46 int flags = fcntl(parent_sync_channel_.get().handle, F_GETFL, 0);
47 PCHECK(flags != -1);
48 PCHECK(fcntl(parent_sync_channel_.get().handle, F_SETFL,
49 flags & ~O_NONBLOCK) != -1);
50
51 std::deque<PlatformHandle> received_handles;
52 char buf[1];
53 ssize_t result = PlatformChannelRecvmsg(parent_sync_channel_.get(), buf, 1,
54 &received_handles, true);
55 CHECK_EQ(1, result);
56 CHECK_EQ(1u, received_handles.size());
57 parent_async_channel_handle.reset(received_handles.front());
58 #else
59 HANDLE parent_handle = INVALID_HANDLE_VALUE; 39 HANDLE parent_handle = INVALID_HANDLE_VALUE;
60 DWORD bytes_read = 0; 40 DWORD bytes_read = 0;
61 BOOL rv = ReadFile(parent_sync_channel_.get().handle, &parent_handle, 41 BOOL rv = ReadFile(parent_sync_channel_.get().handle, &parent_handle,
62 sizeof(parent_handle), &bytes_read, NULL); 42 sizeof(parent_handle), &bytes_read, NULL);
63 CHECK(rv); 43 CHECK(rv);
64 parent_async_channel_handle.reset(PlatformHandle(parent_handle)); 44 parent_async_channel_handle.reset(PlatformHandle(parent_handle));
45 sync_channel_lock_.Unlock();
65 #endif 46 #endif
66 sync_channel_lock_.Unlock();
67 47
68 internal::g_io_thread_task_runner->PostTask( 48 internal::g_io_thread_task_runner->PostTask(
69 FROM_HERE, 49 FROM_HERE,
70 base::Bind(&ChildBroker::InitAsyncChannel, base::Unretained(this), 50 base::Bind(&ChildBroker::InitAsyncChannel, base::Unretained(this),
71 base::Passed(&parent_async_channel_handle))); 51 base::Passed(&parent_async_channel_handle)));
72 } 52 }
73 53
74 #if defined(OS_WIN) 54 #if defined(OS_WIN)
75 void ChildBroker::CreatePlatformChannelPair( 55 void ChildBroker::CreatePlatformChannelPair(
76 ScopedPlatformHandle* server, ScopedPlatformHandle* client) { 56 ScopedPlatformHandle* server, ScopedPlatformHandle* client) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 std::vector<HANDLE> handles_temp(count); 92 std::vector<HANDLE> handles_temp(count);
113 uint32_t response_size = 93 uint32_t response_size =
114 static_cast<uint32_t>(handles_temp.size()) * sizeof(HANDLE); 94 static_cast<uint32_t>(handles_temp.size()) * sizeof(HANDLE);
115 sync_channel_lock_.Lock(); 95 sync_channel_lock_.Lock();
116 if (WriteAndReadResponse(message, &handles_temp[0], response_size)) { 96 if (WriteAndReadResponse(message, &handles_temp[0], response_size)) {
117 for (uint32_t i = 0; i < count; ++i) 97 for (uint32_t i = 0; i < count; ++i)
118 handles[i].handle = handles_temp[i]; 98 handles[i].handle = handles_temp[i];
119 sync_channel_lock_.Unlock(); 99 sync_channel_lock_.Unlock();
120 } 100 }
121 } 101 }
122 #else
123 scoped_refptr<PlatformSharedBuffer> ChildBroker::CreateSharedBuffer(
124 size_t num_bytes) {
125 sync_channel_lock_.Lock();
126 scoped_refptr<PlatformSharedBuffer> shared_buffer;
127
128 BrokerMessage message;
129 message.size = kBrokerMessageHeaderSize + sizeof(uint32_t);
130 message.id = CREATE_SHARED_BUFFER;
131 message.shared_buffer_size = num_bytes;
132
133 std::deque<PlatformHandle> handles;
134 if (WriteAndReadHandles(&message, &handles)) {
135 DCHECK_EQ(1u, handles.size());
136 PlatformHandle handle = handles.front();
137 if (handle.is_valid())
138 shared_buffer =
139 internal::g_platform_support->CreateSharedBufferFromHandle(
140 num_bytes, ScopedPlatformHandle(handles.front()));
141 }
142 sync_channel_lock_.Unlock();
143 return shared_buffer;
144 }
145 #endif 102 #endif
146 103
147 void ChildBroker::ConnectMessagePipe(uint64_t pipe_id, 104 void ChildBroker::ConnectMessagePipe(uint64_t pipe_id,
148 MessagePipeDispatcher* message_pipe) { 105 MessagePipeDispatcher* message_pipe) {
149 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 106 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
150 107
151 ConnectMessagePipeMessage data; 108 ConnectMessagePipeMessage data;
152 memset(&data, 0, sizeof(data)); 109 memset(&data, 0, sizeof(data));
153 data.pipe_id = pipe_id; 110 data.pipe_id = pipe_id;
154 if (pending_connects_.find(pipe_id) != pending_connects_.end()) { 111 if (pending_connects_.find(pipe_id) != pending_connects_.end()) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 connected_pipes_[message_pipe]->RemoveRoute(pipe_id); 165 connected_pipes_[message_pipe]->RemoveRoute(pipe_id);
209 connected_pipes_.erase(message_pipe); 166 connected_pipes_.erase(message_pipe);
210 } 167 }
211 168
212 ChildBroker::ChildBroker() 169 ChildBroker::ChildBroker()
213 : parent_async_channel_(nullptr), 170 : parent_async_channel_(nullptr),
214 in_process_pipes_channel1_(nullptr), 171 in_process_pipes_channel1_(nullptr),
215 in_process_pipes_channel2_(nullptr) { 172 in_process_pipes_channel2_(nullptr) {
216 DCHECK(!internal::g_broker); 173 DCHECK(!internal::g_broker);
217 internal::g_broker = this; 174 internal::g_broker = this;
175 #if defined(OS_WIN)
218 // Block any threads from calling this until we have a pipe to the parent. 176 // Block any threads from calling this until we have a pipe to the parent.
219 sync_channel_lock_.Lock(); 177 sync_channel_lock_.Lock();
178 #endif
220 } 179 }
221 180
222 ChildBroker::~ChildBroker() { 181 ChildBroker::~ChildBroker() {
223 } 182 }
224 183
225 void ChildBroker::OnReadMessage( 184 void ChildBroker::OnReadMessage(
226 const MessageInTransit::View& message_view, 185 const MessageInTransit::View& message_view,
227 ScopedPlatformHandleVectorPtr platform_handles) { 186 ScopedPlatformHandleVectorPtr platform_handles) {
228 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 187 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
229 MultiplexMessages type = 188 MultiplexMessages type =
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 // then when it's read it returns no messages because it doesn't have the 289 // then when it's read it returns no messages because it doesn't have the
331 // channel yet. 290 // channel yet.
332 message_pipe->GotNonTransferableChannel(raw_channel->channel()); 291 message_pipe->GotNonTransferableChannel(raw_channel->channel());
333 // The above call could have caused |CloseMessagePipe| to be called. 292 // The above call could have caused |CloseMessagePipe| to be called.
334 if (connected_pipes_.find(message_pipe) != connected_pipes_.end()) 293 if (connected_pipes_.find(message_pipe) != connected_pipes_.end())
335 raw_channel->AddRoute(pipe_id, message_pipe); 294 raw_channel->AddRoute(pipe_id, message_pipe);
336 } 295 }
337 296
338 #if defined(OS_WIN) 297 #if defined(OS_WIN)
339 298
340 void ChildBroker::CreatePlatformChannelPairNoLock(
341 ScopedPlatformHandle* server,
342 ScopedPlatformHandle* client) {
343 BrokerMessage message;
344 message.size = kBrokerMessageHeaderSize;
345 message.id = CREATE_PLATFORM_CHANNEL_PAIR;
346
347 uint32_t response_size = 2 * sizeof(HANDLE);
348 HANDLE handles[2];
349 if (WriteAndReadResponse(&message, handles, response_size)) {
350 server->reset(PlatformHandle(handles[0]));
351 client->reset(PlatformHandle(handles[1]));
352 }
353 }
354
355 bool ChildBroker::WriteAndReadResponse(BrokerMessage* message, 299 bool ChildBroker::WriteAndReadResponse(BrokerMessage* message,
356 void* response, 300 void* response,
357 uint32_t response_size) { 301 uint32_t response_size) {
358 CHECK(parent_sync_channel_.is_valid()); 302 CHECK(parent_sync_channel_.is_valid());
359 303
360 bool result = true; 304 bool result = true;
361 DWORD bytes_written = 0; 305 DWORD bytes_written = 0;
362 // This will always write in one chunk per 306 // This will always write in one chunk per
363 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150.aspx. 307 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150.aspx.
364 BOOL rv = WriteFile(parent_sync_channel_.get().handle, message, message->size, 308 BOOL rv = WriteFile(parent_sync_channel_.get().handle, message, message->size,
(...skipping 11 matching lines...) Expand all
376 result = false; 320 result = false;
377 break; 321 break;
378 } 322 }
379 response_size -= bytes_read; 323 response_size -= bytes_read;
380 response = static_cast<char*>(response) + bytes_read; 324 response = static_cast<char*>(response) + bytes_read;
381 } 325 }
382 } 326 }
383 327
384 return result; 328 return result;
385 } 329 }
386 #else
387 bool ChildBroker::WriteAndReadHandles(BrokerMessage* message,
388 std::deque<PlatformHandle>* handles) {
389 CHECK(parent_sync_channel_.is_valid());
390 330
391 uint32_t remaining_bytes = message->size; 331 void ChildBroker::CreatePlatformChannelPairNoLock(
392 while (remaining_bytes > 0) { 332 ScopedPlatformHandle* server, ScopedPlatformHandle* client) {
393 ssize_t bytes_written = PlatformChannelWrite( 333 BrokerMessage message;
394 parent_sync_channel_.get(), 334 message.size = kBrokerMessageHeaderSize;
395 reinterpret_cast<uint8_t*>(message) + (message->size - remaining_bytes), 335 message.id = CREATE_PLATFORM_CHANNEL_PAIR;
396 remaining_bytes);
397 336
398 if (bytes_written != -1) 337 uint32_t response_size = 2 * sizeof(HANDLE);
399 remaining_bytes -= bytes_written; 338 HANDLE handles[2];
400 else 339 if (WriteAndReadResponse(&message, handles, response_size)) {
401 return false; 340 server->reset(PlatformHandle(handles[0]));
341 client->reset(PlatformHandle(handles[1]));
402 } 342 }
403 // Perform a blocking read (we set this fd to be blocking in 343 }
404 // SetChildBrokerHostHandle).
405 char buf[1];
406 ssize_t bytes_read = PlatformChannelRecvmsg(
407 parent_sync_channel_.get(), buf, 1, handles, true /* should_block */);
408 // If the other side shutdown, or there was an error, or we didn't get
409 // any handles.
410 if (bytes_read == 0 || bytes_read == -1 || handles->empty())
411 return false;
412 344
413 return true;
414 }
415 #endif 345 #endif
416 346
417 } // namespace edk 347 } // namespace edk
418 } // namespace mojo 348 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/child_broker.h ('k') | mojo/edk/system/child_broker_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698