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

Side by Side Diff: remoting/host/native_messaging/native_messaging_reader.cc

Issue 2207153004: Fixing a hang in the native messaging hosts on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding a comment describing why we need to cancel the pending read operation on Windows. Created 4 years, 4 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 | « no previous file | remoting/host/native_messaging/native_messaging_reader_unittest.cc » ('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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "remoting/host/native_messaging/native_messaging_reader.h" 5 #include "remoting/host/native_messaging/native_messaging_reader.h"
6 6
7 #include <stdint.h> 7 #include <cstdint>
8
9 #include <string> 8 #include <string>
10 #include <utility> 9 #include <utility>
11 10
12 #include "base/bind.h" 11 #include "base/bind.h"
13 #include "base/files/file.h" 12 #include "base/files/file.h"
14 #include "base/json/json_reader.h" 13 #include "base/json/json_reader.h"
15 #include "base/location.h" 14 #include "base/location.h"
16 #include "base/macros.h" 15 #include "base/macros.h"
17 #include "base/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
18 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
19 #include "base/stl_util.h" 18 #include "base/stl_util.h"
20 #include "base/threading/sequenced_worker_pool.h" 19 #include "base/threading/thread.h"
21 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/values.h" 21 #include "base/values.h"
22 #include "build/build_config.h"
23
24 #if defined(OS_WIN)
25 #include <windows.h>
26
27 #include "base/threading/platform_thread.h"
28 #include "base/win/scoped_handle.h"
29 #endif // defined(OS_WIN)
23 30
24 namespace { 31 namespace {
25 32
26 // uint32_t is specified in the protocol as the type for the message header. 33 // uint32_t is specified in the protocol as the type for the message header.
27 typedef uint32_t MessageLengthType; 34 typedef uint32_t MessageLengthType;
28 35
29 const int kMessageHeaderSize = sizeof(MessageLengthType); 36 const int kMessageHeaderSize = sizeof(MessageLengthType);
30 37
31 // Limit the size of received messages, to avoid excessive memory-allocation in 38 // Limit the size of received messages, to avoid excessive memory-allocation in
32 // this process, and potential overflow issues when casting to a signed 32-bit 39 // this process, and potential overflow issues when casting to a signed 32-bit
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 void NativeMessagingReader::Core::NotifyEof() { 137 void NativeMessagingReader::Core::NotifyEof() {
131 DCHECK(read_task_runner_->RunsTasksOnCurrentThread()); 138 DCHECK(read_task_runner_->RunsTasksOnCurrentThread());
132 caller_task_runner_->PostTask( 139 caller_task_runner_->PostTask(
133 FROM_HERE, 140 FROM_HERE,
134 base::Bind(&NativeMessagingReader::InvokeEofCallback, reader_)); 141 base::Bind(&NativeMessagingReader::InvokeEofCallback, reader_));
135 } 142 }
136 143
137 NativeMessagingReader::NativeMessagingReader(base::File file) 144 NativeMessagingReader::NativeMessagingReader(base::File file)
138 : reader_thread_("Reader"), 145 : reader_thread_("Reader"),
139 weak_factory_(this) { 146 weak_factory_(this) {
140 reader_thread_.Start(); 147 reader_thread_.StartWithOptions(
148 base::Thread::Options(base::MessageLoop::TYPE_IO, /*size=*/0));
149
141 read_task_runner_ = reader_thread_.task_runner(); 150 read_task_runner_ = reader_thread_.task_runner();
142 core_.reset(new Core(std::move(file), base::ThreadTaskRunnerHandle::Get(), 151 core_.reset(new Core(std::move(file), base::ThreadTaskRunnerHandle::Get(),
143 read_task_runner_, weak_factory_.GetWeakPtr())); 152 read_task_runner_, weak_factory_.GetWeakPtr()));
144 } 153 }
145 154
146 NativeMessagingReader::~NativeMessagingReader() { 155 NativeMessagingReader::~NativeMessagingReader() {
147 read_task_runner_->DeleteSoon(FROM_HERE, core_.release()); 156 read_task_runner_->DeleteSoon(FROM_HERE, core_.release());
157
158 #if defined(OS_WIN)
159 // The ReadMessage() method uses a blocking read (on all platforms) which
160 // cause a deadlock if the owning thread attempts to destroy this object
161 // while there is a read operation pending.
162 // On POSIX platforms, closing the write end of the pipe causes the Chrome
163 // process to close the read end so that this class can be cleaned up.
164 // On Windows, closing the write end of the pipe does nothing as the parent
165 // process is cmd.exe which doesn't care. Thus, the read end of the pipe
166 // remains open, the read operation is blocked, and we hang in the d'tor.
167 // Canceling the pending I/O here prevents the hang on Windows and isn't
168 // needed for POSIX since it works correctly.
169 base::PlatformThreadId thread_id = reader_thread_.GetThreadId();
170 base::win::ScopedHandle thread_handle(
171 OpenThread(THREAD_TERMINATE, /*bInheritHandle=*/false, thread_id));
172 if (!CancelSynchronousIo(thread_handle.Get())) {
173 // ERROR_NOT_FOUND means there were no pending IO requests so don't treat
174 // that result as an error.
175 if (GetLastError() != ERROR_NOT_FOUND) {
176 PLOG(ERROR) << "CancelSynchronousIo() failed";
177 }
178 }
179 #endif // defined(OS_WIN)
148 } 180 }
149 181
150 void NativeMessagingReader::Start(MessageCallback message_callback, 182 void NativeMessagingReader::Start(MessageCallback message_callback,
151 base::Closure eof_callback) { 183 base::Closure eof_callback) {
152 message_callback_ = message_callback; 184 message_callback_ = message_callback;
153 eof_callback_ = eof_callback; 185 eof_callback_ = eof_callback;
154 186
155 // base::Unretained is safe since |core_| is only deleted via the 187 // base::Unretained is safe since |core_| is only deleted via the
156 // DeleteSoon task which is posted from this class's dtor. 188 // DeleteSoon task which is posted from this class's dtor.
157 read_task_runner_->PostTask( 189 read_task_runner_->PostTask(
158 FROM_HERE, base::Bind(&NativeMessagingReader::Core::ReadMessage, 190 FROM_HERE, base::Bind(&NativeMessagingReader::Core::ReadMessage,
159 base::Unretained(core_.get()))); 191 base::Unretained(core_.get())));
160 } 192 }
161 193
162 void NativeMessagingReader::InvokeMessageCallback( 194 void NativeMessagingReader::InvokeMessageCallback(
163 std::unique_ptr<base::Value> message) { 195 std::unique_ptr<base::Value> message) {
164 message_callback_.Run(std::move(message)); 196 message_callback_.Run(std::move(message));
165 } 197 }
166 198
167 void NativeMessagingReader::InvokeEofCallback() { 199 void NativeMessagingReader::InvokeEofCallback() {
168 eof_callback_.Run(); 200 eof_callback_.Run();
169 } 201 }
170 202
171 } // namespace remoting 203 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | remoting/host/native_messaging/native_messaging_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698