| Index: mojo/edk/system/channel_win.cc
|
| diff --git a/mojo/edk/system/channel_win.cc b/mojo/edk/system/channel_win.cc
|
| index 77a19a68ff75d6ece43d2c182982ae90b386da80..f05c55de3500e34794384be498bae907a9c40dbb 100644
|
| --- a/mojo/edk/system/channel_win.cc
|
| +++ b/mojo/edk/system/channel_win.cc
|
| @@ -77,6 +77,9 @@ class ChannelWin : public Channel,
|
| self_(this),
|
| handle_(std::move(handle)),
|
| io_task_runner_(io_task_runner) {
|
| + memset(&connect_context_, 0, sizeof(connect_context_));
|
| + connect_context_.handler = this;
|
| +
|
| memset(&read_context_, 0, sizeof(read_context_));
|
| read_context_.handler = this;
|
|
|
| @@ -141,7 +144,27 @@ class ChannelWin : public Channel,
|
| base::MessageLoopForIO::current()->RegisterIOHandler(
|
| handle_.get().handle, this);
|
|
|
| - // Now that we have registered our IOHandler, we can start writing.
|
| + // We may be starting the channel with a disconnected server pipe, e.g.,
|
| + // when not using PlatformChannelPair. Make sure the pipe is connected
|
| + // before we attempt to do any reading or writing.
|
| + BOOL result = ConnectNamedPipe(handle_.get().handle,
|
| + &connect_context_.overlapped);
|
| + if (!result && (GetLastError() == ERROR_PIPE_CONNECTED ||
|
| + GetLastError() == ERROR_INVALID_FUNCTION)) {
|
| + // If the pipe's already connected, we can start using it immediately.
|
| + // Note that ERROR_INVALID_FUNCTION is returned if we call this on a
|
| + // client pipe. If this is a client pipe we know it's already connected.
|
| + OnPipeConnected();
|
| + } else if (result || GetLastError() == ERROR_IO_PENDING) {
|
| + // Balanced in OnIOCompleted.
|
| + AddRef();
|
| + } else {
|
| + OnError();
|
| + }
|
| + }
|
| +
|
| + void OnPipeConnected() {
|
| + // Now that we are connected we can start writing and reading.
|
| {
|
| base::AutoLock lock(write_lock_);
|
| if (delay_writes_) {
|
| @@ -180,9 +203,11 @@ class ChannelWin : public Channel,
|
| OnError();
|
| } else if (context == &read_context_) {
|
| OnReadDone(static_cast<size_t>(bytes_transfered));
|
| - } else {
|
| - CHECK(context == &write_context_);
|
| + } else if (context == &write_context_) {
|
| OnWriteDone(static_cast<size_t>(bytes_transfered));
|
| + } else {
|
| + CHECK(context == &connect_context_);
|
| + OnPipeConnected();
|
| }
|
| Release(); // Balancing reference taken after ReadFile / WriteFile.
|
| }
|
| @@ -276,6 +301,7 @@ class ChannelWin : public Channel,
|
| ScopedPlatformHandle handle_;
|
| scoped_refptr<base::TaskRunner> io_task_runner_;
|
|
|
| + base::MessageLoopForIO::IOContext connect_context_;
|
| base::MessageLoopForIO::IOContext read_context_;
|
| base::MessageLoopForIO::IOContext write_context_;
|
|
|
|
|