OLD | NEW |
---|---|
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 #include "mojo/edk/system/channel.h" | 5 #include "mojo/edk/system/channel.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <windows.h> | 8 #include <windows.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 self_(this), | 78 self_(this), |
79 handle_(std::move(handle)), | 79 handle_(std::move(handle)), |
80 io_task_runner_(io_task_runner) { | 80 io_task_runner_(io_task_runner) { |
81 sentinel_ = ~reinterpret_cast<uintptr_t>(this); | 81 sentinel_ = ~reinterpret_cast<uintptr_t>(this); |
82 CHECK(handle_.is_valid()); | 82 CHECK(handle_.is_valid()); |
83 memset(&read_context_, 0, sizeof(read_context_)); | 83 memset(&read_context_, 0, sizeof(read_context_)); |
84 read_context_.handler = this; | 84 read_context_.handler = this; |
85 | 85 |
86 memset(&write_context_, 0, sizeof(write_context_)); | 86 memset(&write_context_, 0, sizeof(write_context_)); |
87 write_context_.handler = this; | 87 write_context_.handler = this; |
88 | |
89 wait_for_connect_ = handle_.get().needs_connection; | |
88 } | 90 } |
89 | 91 |
90 void Start() override { | 92 void Start() override { |
91 io_task_runner_->PostTask( | 93 io_task_runner_->PostTask( |
92 FROM_HERE, base::Bind(&ChannelWin::StartOnIOThread, this)); | 94 FROM_HERE, base::Bind(&ChannelWin::StartOnIOThread, this)); |
93 } | 95 } |
94 | 96 |
95 void ShutDownImpl() override { | 97 void ShutDownImpl() override { |
96 // Always shut down asynchronously when called through the public interface. | 98 // Always shut down asynchronously when called through the public interface. |
97 io_task_runner_->PostTask( | 99 io_task_runner_->PostTask( |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 // value lets us detect the difference between just destroying, and | 143 // value lets us detect the difference between just destroying, and |
142 // re-allocating the memory. | 144 // re-allocating the memory. |
143 sentinel_ = UINTPTR_MAX; | 145 sentinel_ = UINTPTR_MAX; |
144 } | 146 } |
145 | 147 |
146 void StartOnIOThread() { | 148 void StartOnIOThread() { |
147 base::MessageLoop::current()->AddDestructionObserver(this); | 149 base::MessageLoop::current()->AddDestructionObserver(this); |
148 base::MessageLoopForIO::current()->RegisterIOHandler( | 150 base::MessageLoopForIO::current()->RegisterIOHandler( |
149 handle_.get().handle, this); | 151 handle_.get().handle, this); |
150 | 152 |
153 if (wait_for_connect_) { | |
154 BOOL ok = ConnectNamedPipe(handle_.get().handle, | |
155 &read_context_.overlapped); | |
Ken Rockot(use gerrit already)
2016/05/10 22:41:28
I'd rather we use a separate IO context for connec
Anand Mistry (off Chromium)
2016/05/11 04:15:20
Done.
| |
156 if (ok) { | |
157 PLOG(ERROR) << "Unexpected success while waiting for pipe connection"; | |
158 OnError(); | |
159 return; | |
160 } | |
161 | |
162 const DWORD err = GetLastError(); | |
163 switch (err) { | |
164 case ERROR_PIPE_CONNECTED: | |
165 wait_for_connect_ = false; | |
166 break; | |
167 case ERROR_IO_PENDING: | |
168 AddRef(); | |
169 return; | |
170 case ERROR_NO_DATA: | |
171 OnError(); | |
172 return; | |
173 } | |
174 } | |
175 | |
151 // Now that we have registered our IOHandler, we can start writing. | 176 // Now that we have registered our IOHandler, we can start writing. |
152 { | 177 { |
153 base::AutoLock lock(write_lock_); | 178 base::AutoLock lock(write_lock_); |
154 if (delay_writes_) { | 179 if (delay_writes_) { |
155 delay_writes_ = false; | 180 delay_writes_ = false; |
156 WriteNextNoLock(); | 181 WriteNextNoLock(); |
157 } | 182 } |
158 } | 183 } |
159 | 184 |
160 // Keep this alive in case we synchronously run shutdown. | 185 // Keep this alive in case we synchronously run shutdown. |
(...skipping 23 matching lines...) Expand all Loading... | |
184 } | 209 } |
185 | 210 |
186 // base::MessageLoop::IOHandler: | 211 // base::MessageLoop::IOHandler: |
187 void OnIOCompleted(base::MessageLoopForIO::IOContext* context, | 212 void OnIOCompleted(base::MessageLoopForIO::IOContext* context, |
188 DWORD bytes_transfered, | 213 DWORD bytes_transfered, |
189 DWORD error) override { | 214 DWORD error) override { |
190 CheckValid(); | 215 CheckValid(); |
191 if (error != ERROR_SUCCESS) { | 216 if (error != ERROR_SUCCESS) { |
192 OnError(); | 217 OnError(); |
193 } else if (context == &read_context_) { | 218 } else if (context == &read_context_) { |
194 OnReadDone(static_cast<size_t>(bytes_transfered)); | 219 if (wait_for_connect_) { |
220 wait_for_connect_ = false; | |
221 ReadMore(0); | |
222 | |
223 base::AutoLock lock(write_lock_); | |
224 if (delay_writes_) { | |
225 delay_writes_ = false; | |
226 WriteNextNoLock(); | |
227 } | |
228 } else { | |
229 OnReadDone(static_cast<size_t>(bytes_transfered)); | |
230 } | |
195 } else { | 231 } else { |
196 CHECK(context == &write_context_); | 232 CHECK(context == &write_context_); |
197 OnWriteDone(static_cast<size_t>(bytes_transfered)); | 233 OnWriteDone(static_cast<size_t>(bytes_transfered)); |
198 } | 234 } |
199 Release(); // Balancing reference taken after ReadFile / WriteFile. | 235 Release(); // Balancing reference taken after ReadFile / WriteFile. |
200 } | 236 } |
201 | 237 |
202 void OnReadDone(size_t bytes_read) { | 238 void OnReadDone(size_t bytes_read) { |
203 if (bytes_read > 0) { | 239 if (bytes_read > 0) { |
204 size_t next_read_size = 0; | 240 size_t next_read_size = 0; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 | 338 |
303 bool reject_writes_ = false; | 339 bool reject_writes_ = false; |
304 std::deque<MessageView> outgoing_messages_; | 340 std::deque<MessageView> outgoing_messages_; |
305 | 341 |
306 // A value that is unlikely to be valid if this object is destroyed and the | 342 // A value that is unlikely to be valid if this object is destroyed and the |
307 // memory overwritten by something else. When this is valid, its value will be | 343 // memory overwritten by something else. When this is valid, its value will be |
308 // ~|this|. | 344 // ~|this|. |
309 // TODO(amistry): Remove before M50 branch point. | 345 // TODO(amistry): Remove before M50 branch point. |
310 uintptr_t sentinel_; | 346 uintptr_t sentinel_; |
311 | 347 |
348 bool wait_for_connect_; | |
349 | |
312 DISALLOW_COPY_AND_ASSIGN(ChannelWin); | 350 DISALLOW_COPY_AND_ASSIGN(ChannelWin); |
313 }; | 351 }; |
314 | 352 |
315 } // namespace | 353 } // namespace |
316 | 354 |
317 // static | 355 // static |
318 scoped_refptr<Channel> Channel::Create( | 356 scoped_refptr<Channel> Channel::Create( |
319 Delegate* delegate, | 357 Delegate* delegate, |
320 ScopedPlatformHandle platform_handle, | 358 ScopedPlatformHandle platform_handle, |
321 scoped_refptr<base::TaskRunner> io_task_runner) { | 359 scoped_refptr<base::TaskRunner> io_task_runner) { |
322 return new ChannelWin(delegate, std::move(platform_handle), io_task_runner); | 360 return new ChannelWin(delegate, std::move(platform_handle), io_task_runner); |
323 } | 361 } |
324 | 362 |
325 } // namespace edk | 363 } // namespace edk |
326 } // namespace mojo | 364 } // namespace mojo |
OLD | NEW |