Chromium Code Reviews| 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 |