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

Side by Side Diff: mojo/edk/system/parent_token_serializer_win.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: small cleanup Created 5 years, 1 month 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mojo/edk/system/parent_token_serializer_win.h"
6
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "mojo/edk/embedder/platform_channel_pair.h"
10 #include "mojo/edk/system/configuration.h"
11 #include "mojo/edk/system/parent_token_serializer_state_win.h"
12 #include "mojo/edk/system/token_serializer_messages_win.h"
13
14 namespace mojo {
15 namespace edk {
16
17 namespace {
18 static const int kDefaultReadBufferSize = 256;
19 }
20
21 ParentTokenSerializer::ParentTokenSerializer(HANDLE child_process,
22 ScopedPlatformHandle pipe)
23 : child_process_(child_process),
24 pipe_(pipe.Pass()),
25 num_bytes_read_(0) {
26 memset(&read_context_.overlapped, 0, sizeof(read_context_.overlapped));
27 read_context_.handler = this;
28 memset(&write_context_.overlapped, 0, sizeof(write_context_.overlapped));
29 write_context_.handler = this;
30
31 ParentTokenSerializerState::GetInstance()->token_serialize_thread()->PostTask(
32 FROM_HERE,
33 base::Bind(&ParentTokenSerializer::RegisterIOHandler,
34 base::Unretained(this)));
35 read_data_.resize(kDefaultReadBufferSize);
yzshen1 2015/11/20 20:39:55 Please move this resize() above the post task. Bec
jam 2015/11/21 01:26:09 done, good catch
36 }
37
38 ParentTokenSerializer::~ParentTokenSerializer() {
39 }
40
41 void ParentTokenSerializer::RegisterIOHandler() {
42 base::MessageLoopForIO::current()->RegisterIOHandler(
43 pipe_.get().handle, this);
44 BeginRead();
45 }
46
47 void ParentTokenSerializer::BeginRead() {
48 BOOL rv = ReadFile(pipe_.get().handle, &read_data_[num_bytes_read_],
49 static_cast<int>(read_data_.size() - num_bytes_read_),
50 nullptr, &read_context_.overlapped);
51 DCHECK(rv ||
52 GetLastError() == ERROR_IO_PENDING ||
53 GetLastError() == ERROR_BROKEN_PIPE);
yzshen1 2015/11/20 20:39:55 When the result is ERROR_BROKEN_PIPE, do we still
jam 2015/11/21 01:26:09 good point, deleted for broken pipe case
54 }
55
56 void ParentTokenSerializer::OnIOCompleted(
57 base::MessageLoopForIO::IOContext* context,
58 DWORD bytes_transferred,
59 DWORD error) {
60 if (context != &read_context_)
61 return;
62
63 if (error == ERROR_BROKEN_PIPE) {
64 delete this;
65 return; // Child process exited or crashed.
66 }
67
68 if (error != ERROR_SUCCESS) {
69 NOTREACHED() << "Error " << error << " in ParentTokenSerializer.";
70 delete this;
71 return;
72 }
73
74 num_bytes_read_ += bytes_transferred;
75 CHECK_GE(num_bytes_read_, sizeof(uint32_t));
76 TokenSerializerMessage* message =
77 reinterpret_cast<TokenSerializerMessage*>(&read_data_[0]);
78 if (num_bytes_read_ < message->size) {
79 read_data_.resize(message->size);
80 BeginRead();
81 return;
82 }
83
84 if (message->id == CREATE_PLATFORM_CHANNEL_PAIR) {
85 PlatformChannelPair channel_pair;
86 uint32_t response_size = 2 * sizeof(HANDLE);
87 write_data_.resize(response_size);
88 HANDLE* handles = reinterpret_cast<HANDLE*>(&write_data_[0]);
89 handles[0] = DuplicateToChild(
90 channel_pair.PassServerHandle().release().handle);
91 handles[1] = DuplicateToChild(
92 channel_pair.PassClientHandle().release().handle);
93 } else if (message->id == HANDLE_TO_TOKEN) {
94 uint32_t count =
95 (message->size - kTokenSerializerMessageHeaderSize) / sizeof(HANDLE);
96 if (count > GetConfiguration().max_message_num_handles) {
97 NOTREACHED() << "Too many handles from child process. Closing channel.";
98 delete this;
99 return;
100 }
101 uint32_t response_size = count * sizeof(uint64_t);
102 write_data_.resize(response_size);
103 uint64_t* tokens = reinterpret_cast<uint64_t*>(&write_data_[0]);
104 std::vector<PlatformHandle> duplicated_handles(count);
105 for (uint32_t i = 0; i < count; ++i) {
106 duplicated_handles[i] =
107 PlatformHandle(DuplicateFromChild(message->handles[i]));
108 }
109 ParentTokenSerializerState::GetInstance()->HandleToToken(
110 &duplicated_handles[0], count, tokens);
111 } else if (message->id == TOKEN_TO_HANDLE) {
112 uint32_t count =
113 (message->size - kTokenSerializerMessageHeaderSize) /
114 sizeof(uint64_t);
115 if (count > GetConfiguration().max_message_num_handles) {
116 NOTREACHED() << "Too many tokens from child process. Closing channel.";
117 delete this;
118 return;
119 }
120 uint32_t response_size = count * sizeof(HANDLE);
121 write_data_.resize(response_size);
122 HANDLE* handles = reinterpret_cast<HANDLE*>(&write_data_[0]);
123 std::vector<PlatformHandle> temp_handles(count);
124 ParentTokenSerializerState::GetInstance()->TokenToHandle(
125 &message->tokens[0], count, &temp_handles[0]);
126 for (uint32_t i = 0; i < count; ++i) {
127 if (temp_handles[i].is_valid()) {
128 handles[i] = DuplicateToChild(temp_handles[i].handle);
129 } else {
130 NOTREACHED() << "Unknown token";
131 handles[i] = INVALID_HANDLE_VALUE;
132 }
133 }
134 } else {
135 NOTREACHED() << "Unknown command. Stopping reading.";
136 delete this;
137 return;
138 }
139
140 BOOL rv = WriteFile(pipe_.get().handle, &write_data_[0],
yzshen1 2015/11/20 20:39:55 I think it is not guaranteed that the write could
jam 2015/11/21 01:26:09 since this side uses overlapped IO (as opposed to
141 static_cast<int>(write_data_.size()), NULL,
142 &write_context_.overlapped);
143 DCHECK(rv);
144
145 // Start reading again.
146 num_bytes_read_ = 0;
147 BeginRead();
148 }
149
150
151 HANDLE ParentTokenSerializer::DuplicateToChild(HANDLE handle) {
152 HANDLE rv = INVALID_HANDLE_VALUE;
153 BOOL result = DuplicateHandle(base::GetCurrentProcessHandle(), handle,
154 child_process_, &rv, 0, FALSE,
155 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
156 DCHECK(result);
157 return rv;
158 }
159
160 HANDLE ParentTokenSerializer::DuplicateFromChild(HANDLE handle) {
161 HANDLE rv = INVALID_HANDLE_VALUE;
162 BOOL result = DuplicateHandle(child_process_, handle,
163 base::GetCurrentProcessHandle(), &rv, 0, FALSE,
164 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
165 DCHECK(result);
166 return rv;
167 }
168
169 } // namespace edk
170 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698