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

Side by Side Diff: device/serial/serial_io_handler_win.cc

Issue 1460743002: Revert of Reland: Add code to deal with serial device disconnection detection on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « device/serial/serial_io_handler_win.h ('k') | device/usb/usb.gyp » ('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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <windows.h>
6
5 #include "device/serial/serial_io_handler_win.h" 7 #include "device/serial/serial_io_handler_win.h"
6 8
7 #include <windows.h>
8 #include <setupapi.h>
9
10 #include "base/bind.h"
11 #include "base/scoped_observer.h"
12 #include "base/threading/thread_checker.h"
13 #include "device/core/device_info_query_win.h"
14 #include "device/core/device_monitor_win.h"
15 #include "third_party/re2/re2/re2.h"
16
17 namespace device { 9 namespace device {
18 10
19 namespace { 11 namespace {
20 12
21 int BitrateToSpeedConstant(int bitrate) { 13 int BitrateToSpeedConstant(int bitrate) {
22 #define BITRATE_TO_SPEED_CASE(x) \ 14 #define BITRATE_TO_SPEED_CASE(x) \
23 case x: \ 15 case x: \
24 return CBR_##x; 16 return CBR_##x;
25 switch (bitrate) { 17 switch (bitrate) {
26 BITRATE_TO_SPEED_CASE(110); 18 BITRATE_TO_SPEED_CASE(110);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 serial::StopBits StopBitsConstantToEnum(int stop_bits) { 123 serial::StopBits StopBitsConstantToEnum(int stop_bits) {
132 switch (stop_bits) { 124 switch (stop_bits) {
133 case TWOSTOPBITS: 125 case TWOSTOPBITS:
134 return serial::STOP_BITS_TWO; 126 return serial::STOP_BITS_TWO;
135 case ONESTOPBIT: 127 case ONESTOPBIT:
136 default: 128 default:
137 return serial::STOP_BITS_ONE; 129 return serial::STOP_BITS_ONE;
138 } 130 }
139 } 131 }
140 132
141 // Searches for the COM port in the device's friendly name, assigns its value to
142 // com_port, and returns whether the operation was successful.
143 bool GetCOMPort(const std::string friendly_name, std::string* com_port) {
144 return RE2::PartialMatch(friendly_name, ".* \\((COM[0-9]+)\\)", com_port);
145 }
146
147 } // namespace 133 } // namespace
148 134
149 // static 135 // static
150 scoped_refptr<SerialIoHandler> SerialIoHandler::Create( 136 scoped_refptr<SerialIoHandler> SerialIoHandler::Create(
151 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, 137 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner,
152 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) { 138 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) {
153 return new SerialIoHandlerWin(file_thread_task_runner, ui_thread_task_runner); 139 return new SerialIoHandlerWin(file_thread_task_runner, ui_thread_task_runner);
154 } 140 }
155 141
156 class SerialIoHandlerWin::UiThreadHelper : public DeviceMonitorWin::Observer {
157 public:
158 UiThreadHelper(
159 base::WeakPtr<SerialIoHandlerWin> io_handler,
160 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner)
161 : device_observer_(this),
162 io_handler_(io_handler),
163 io_thread_task_runner_(io_thread_task_runner) {}
164
165 ~UiThreadHelper() { DCHECK(thread_checker_.CalledOnValidThread()); }
166
167 static void Start(UiThreadHelper* self) {
168 self->thread_checker_.DetachFromThread();
169 DeviceMonitorWin* device_monitor = DeviceMonitorWin::GetForAllInterfaces();
170 if (device_monitor)
171 self->device_observer_.Add(device_monitor);
172 }
173
174 private:
175 // DeviceMonitorWin::Observer
176 void OnDeviceRemoved(const GUID& class_guid,
177 const std::string& device_path) override {
178 DCHECK(thread_checker_.CalledOnValidThread());
179 io_thread_task_runner_->PostTask(
180 FROM_HERE, base::Bind(&SerialIoHandlerWin::OnDeviceRemoved, io_handler_,
181 device_path));
182 }
183
184 base::ThreadChecker thread_checker_;
185 ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_;
186
187 // This weak pointer is only valid when checked on this task runner.
188 base::WeakPtr<SerialIoHandlerWin> io_handler_;
189 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
190
191 DISALLOW_COPY_AND_ASSIGN(UiThreadHelper);
192 };
193
194 void SerialIoHandlerWin::OnDeviceRemoved(const std::string& device_path) {
195 DCHECK(CalledOnValidThread());
196
197 DeviceInfoQueryWin device_info_query;
198 if (!device_info_query.device_info_list_valid()) {
199 DVPLOG(1) << "Failed to create a device information set";
200 return;
201 }
202
203 // This will add the device so we can query driver info.
204 if (!device_info_query.AddDevice(device_path.c_str())) {
205 DVPLOG(1) << "Failed to get device interface data for " << device_path;
206 return;
207 }
208
209 if (!device_info_query.GetDeviceInfo()) {
210 DVPLOG(1) << "Failed to get device info for " << device_path;
211 return;
212 }
213
214 std::string friendly_name;
215 if (!device_info_query.GetDeviceStringProperty(SPDRP_FRIENDLYNAME,
216 &friendly_name)) {
217 DVPLOG(1) << "Failed to get device service property";
218 return;
219 }
220
221 std::string com_port;
222 if (!GetCOMPort(friendly_name, &com_port)) {
223 DVPLOG(1) << "Failed to get port name from \"" << friendly_name << "\".";
224 return;
225 }
226
227 if (port() == com_port)
228 CancelRead(serial::RECEIVE_ERROR_DISCONNECTED);
229 }
230
231 bool SerialIoHandlerWin::PostOpen() { 142 bool SerialIoHandlerWin::PostOpen() {
232 DCHECK(!comm_context_); 143 DCHECK(!comm_context_);
233 DCHECK(!read_context_); 144 DCHECK(!read_context_);
234 DCHECK(!write_context_); 145 DCHECK(!write_context_);
235 146
236 base::MessageLoopForIO::current()->RegisterIOHandler(file().GetPlatformFile(), 147 base::MessageLoopForIO::current()->RegisterIOHandler(file().GetPlatformFile(),
237 this); 148 this);
238 149
239 comm_context_.reset(new base::MessageLoopForIO::IOContext()); 150 comm_context_.reset(new base::MessageLoopForIO::IOContext());
240 comm_context_->handler = this; 151 comm_context_->handler = this;
241 memset(&comm_context_->overlapped, 0, sizeof(comm_context_->overlapped)); 152 memset(&comm_context_->overlapped, 0, sizeof(comm_context_->overlapped));
242 153
243 read_context_.reset(new base::MessageLoopForIO::IOContext()); 154 read_context_.reset(new base::MessageLoopForIO::IOContext());
244 read_context_->handler = this; 155 read_context_->handler = this;
245 memset(&read_context_->overlapped, 0, sizeof(read_context_->overlapped)); 156 memset(&read_context_->overlapped, 0, sizeof(read_context_->overlapped));
246 157
247 write_context_.reset(new base::MessageLoopForIO::IOContext()); 158 write_context_.reset(new base::MessageLoopForIO::IOContext());
248 write_context_->handler = this; 159 write_context_->handler = this;
249 memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped)); 160 memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped));
250 161
251 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner =
252 base::ThreadTaskRunnerHandle::Get();
253 helper_ =
254 new UiThreadHelper(weak_factory_.GetWeakPtr(), io_thread_task_runner);
255 ui_thread_task_runner()->PostTask(
256 FROM_HERE, base::Bind(&UiThreadHelper::Start, helper_));
257
258 // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete 162 // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete
259 // immediately with any data that's available, even if there is none. 163 // immediately with any data that's available, even if there is none.
260 // This is OK because we never issue a read request until WaitCommEvent 164 // This is OK because we never issue a read request until WaitCommEvent
261 // signals that data is available. 165 // signals that data is available.
262 COMMTIMEOUTS timeouts = {0}; 166 COMMTIMEOUTS timeouts = {0};
263 timeouts.ReadIntervalTimeout = MAXDWORD; 167 timeouts.ReadIntervalTimeout = MAXDWORD;
264 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) { 168 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) {
265 VPLOG(1) << "Failed to set serial timeouts"; 169 VPLOG(1) << "Failed to set serial timeouts";
266 return false; 170 return false;
267 } 171 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 return false; 264 return false;
361 } 265 }
362 return true; 266 return true;
363 } 267 }
364 268
365 SerialIoHandlerWin::SerialIoHandlerWin( 269 SerialIoHandlerWin::SerialIoHandlerWin(
366 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, 270 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner,
367 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) 271 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
368 : SerialIoHandler(file_thread_task_runner, ui_thread_task_runner), 272 : SerialIoHandler(file_thread_task_runner, ui_thread_task_runner),
369 event_mask_(0), 273 event_mask_(0),
370 is_comm_pending_(false), 274 is_comm_pending_(false) {
371 weak_factory_(this) {} 275 }
372 276
373 SerialIoHandlerWin::~SerialIoHandlerWin() { 277 SerialIoHandlerWin::~SerialIoHandlerWin() {
374 ui_thread_task_runner()->DeleteSoon(FROM_HERE, helper_);
375 } 278 }
376 279
377 void SerialIoHandlerWin::OnIOCompleted( 280 void SerialIoHandlerWin::OnIOCompleted(
378 base::MessageLoopForIO::IOContext* context, 281 base::MessageLoopForIO::IOContext* context,
379 DWORD bytes_transferred, 282 DWORD bytes_transferred,
380 DWORD error) { 283 DWORD error) {
381 DCHECK(CalledOnValidThread()); 284 DCHECK(CalledOnValidThread());
382 if (context == comm_context_) { 285 if (context == comm_context_) {
383 DWORD errors; 286 DWORD errors;
384 COMSTAT status; 287 COMSTAT status;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { 434 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) {
532 // For COM numbers less than 9, CreateFile is called with a string such as 435 // For COM numbers less than 9, CreateFile is called with a string such as
533 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. 436 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added.
534 if (port_name.length() > std::string("COM9").length()) 437 if (port_name.length() > std::string("COM9").length())
535 return std::string("\\\\.\\").append(port_name); 438 return std::string("\\\\.\\").append(port_name);
536 439
537 return port_name; 440 return port_name;
538 } 441 }
539 442
540 } // namespace device 443 } // namespace device
OLDNEW
« no previous file with comments | « device/serial/serial_io_handler_win.h ('k') | device/usb/usb.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698