Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "device/serial/serial_io_handler_posix.h" | 5 #include "device/serial/serial_io_handler_posix.h" |
| 6 | 6 |
| 7 #include <sys/ioctl.h> | 7 #include <sys/ioctl.h> |
| 8 #include <termios.h> | 8 #include <termios.h> |
| 9 | 9 |
| 10 #include "base/posix/eintr_wrapper.h" | 10 #include "base/posix/eintr_wrapper.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 return new SerialIoHandlerPosix(file_thread_task_runner, | 117 return new SerialIoHandlerPosix(file_thread_task_runner, |
| 118 ui_thread_task_runner); | 118 ui_thread_task_runner); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void SerialIoHandlerPosix::ReadImpl() { | 121 void SerialIoHandlerPosix::ReadImpl() { |
| 122 DCHECK(CalledOnValidThread()); | 122 DCHECK(CalledOnValidThread()); |
| 123 DCHECK(pending_read_buffer()); | 123 DCHECK(pending_read_buffer()); |
| 124 DCHECK(file().IsValid()); | 124 DCHECK(file().IsValid()); |
| 125 | 125 |
| 126 EnsureWatchingReads(); | 126 EnsureWatchingReads(); |
| 127 | |
| 128 // Try to read immediately. This is needed because on some platforms | |
| 129 // (e.g., OSX) there may not be a notification from the message loop | |
| 130 // when the fd is ready to read immediately after it is opened. There | |
| 131 // is no danger of blocking because the fd is opened with async flag. | |
| 132 AttemptRead(true); | |
| 127 } | 133 } |
| 128 | 134 |
| 129 void SerialIoHandlerPosix::WriteImpl() { | 135 void SerialIoHandlerPosix::WriteImpl() { |
| 130 DCHECK(CalledOnValidThread()); | 136 DCHECK(CalledOnValidThread()); |
| 131 DCHECK(pending_write_buffer()); | 137 DCHECK(pending_write_buffer()); |
| 132 DCHECK(file().IsValid()); | 138 DCHECK(file().IsValid()); |
| 133 | 139 |
| 134 EnsureWatchingWrites(); | 140 EnsureWatchingWrites(); |
| 135 } | 141 } |
| 136 | 142 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 is_watching_writes_(false) { | 293 is_watching_writes_(false) { |
| 288 } | 294 } |
| 289 | 295 |
| 290 SerialIoHandlerPosix::~SerialIoHandlerPosix() { | 296 SerialIoHandlerPosix::~SerialIoHandlerPosix() { |
| 291 } | 297 } |
| 292 | 298 |
| 293 void SerialIoHandlerPosix::OnFileCanReadWithoutBlocking(int fd) { | 299 void SerialIoHandlerPosix::OnFileCanReadWithoutBlocking(int fd) { |
| 294 DCHECK(CalledOnValidThread()); | 300 DCHECK(CalledOnValidThread()); |
| 295 DCHECK_EQ(fd, file().GetPlatformFile()); | 301 DCHECK_EQ(fd, file().GetPlatformFile()); |
| 296 | 302 |
| 303 AttemptRead(false); | |
| 304 } | |
| 305 | |
| 306 void SerialIoHandlerPosix::AttemptRead(bool within_read) { | |
| 297 if (pending_read_buffer()) { | 307 if (pending_read_buffer()) { |
| 298 int bytes_read = HANDLE_EINTR(read(file().GetPlatformFile(), | 308 int bytes_read = HANDLE_EINTR(read(file().GetPlatformFile(), |
| 299 pending_read_buffer(), | 309 pending_read_buffer(), |
| 300 pending_read_buffer_len())); | 310 pending_read_buffer_len())); |
| 301 if (bytes_read < 0) { | 311 if (bytes_read < 0) { |
| 302 if (errno == ENXIO) { | 312 if (errno == EAGAIN) { |
| 303 ReadCompleted(0, serial::ReceiveError::DEVICE_LOST); | 313 // The fd does not have data to read yet so continue waiting. |
| 314 return; | |
| 315 } else if (errno == ENXIO) { | |
| 316 RunReadCompleted(within_read, 0, serial::ReceiveError::DEVICE_LOST); | |
| 304 } else { | 317 } else { |
| 305 ReadCompleted(0, serial::ReceiveError::SYSTEM_ERROR); | 318 RunReadCompleted(within_read, 0, serial::ReceiveError::SYSTEM_ERROR); |
| 306 } | 319 } |
| 307 } else if (bytes_read == 0) { | 320 } else if (bytes_read == 0) { |
| 308 ReadCompleted(0, serial::ReceiveError::DEVICE_LOST); | 321 RunReadCompleted(within_read, 0, serial::ReceiveError::DEVICE_LOST); |
| 309 } else { | 322 } else { |
| 310 bool break_detected = false; | 323 bool break_detected = false; |
| 311 bool parity_error_detected = false; | 324 bool parity_error_detected = false; |
| 312 int new_bytes_read = | 325 int new_bytes_read = |
| 313 CheckReceiveError(pending_read_buffer(), pending_read_buffer_len(), | 326 CheckReceiveError(pending_read_buffer(), pending_read_buffer_len(), |
| 314 bytes_read, break_detected, parity_error_detected); | 327 bytes_read, break_detected, parity_error_detected); |
| 315 | 328 |
| 316 if (break_detected) { | 329 if (break_detected) { |
| 317 ReadCompleted(new_bytes_read, serial::ReceiveError::BREAK); | 330 RunReadCompleted(within_read, new_bytes_read, |
| 331 serial::ReceiveError::BREAK); | |
| 318 } else if (parity_error_detected) { | 332 } else if (parity_error_detected) { |
| 319 ReadCompleted(new_bytes_read, serial::ReceiveError::PARITY_ERROR); | 333 RunReadCompleted(within_read, new_bytes_read, |
| 334 serial::ReceiveError::PARITY_ERROR); | |
| 320 } else { | 335 } else { |
| 321 ReadCompleted(new_bytes_read, serial::ReceiveError::NONE); | 336 RunReadCompleted(within_read, new_bytes_read, |
| 337 serial::ReceiveError::NONE); | |
| 322 } | 338 } |
| 323 } | 339 } |
| 324 } else { | 340 } else { |
| 325 // Stop watching the fd if we get notifications with no pending | 341 // Stop watching the fd if we get notifications with no pending |
| 326 // reads or writes to avoid starving the message loop. | 342 // reads or writes to avoid starving the message loop. |
| 327 is_watching_reads_ = false; | 343 is_watching_reads_ = false; |
| 328 file_read_watcher_.StopWatchingFileDescriptor(); | 344 file_read_watcher_.StopWatchingFileDescriptor(); |
| 329 } | 345 } |
| 330 } | 346 } |
| 331 | 347 |
| 348 void SerialIoHandlerPosix::RunReadCompleted(bool within_read, | |
| 349 int bytes_read, | |
| 350 serial::ReceiveError error) { | |
| 351 if (within_read) { | |
| 352 // Stop watching the fd because a read completed within the read call. | |
|
Reilly Grant (use Gerrit)
2016/07/27 21:23:38
This isn't necessary. The code is optimized to ass
aschulman
2016/07/28 03:11:00
I think I may be confused. In your prior comment y
| |
| 353 is_watching_reads_ = false; | |
| 354 file_read_watcher_.StopWatchingFileDescriptor(); | |
| 355 | |
| 356 QueueReadCompleted(bytes_read, error); | |
| 357 } else { | |
| 358 ReadCompleted(bytes_read, error); | |
| 359 } | |
| 360 } | |
| 361 | |
| 332 void SerialIoHandlerPosix::OnFileCanWriteWithoutBlocking(int fd) { | 362 void SerialIoHandlerPosix::OnFileCanWriteWithoutBlocking(int fd) { |
| 333 DCHECK(CalledOnValidThread()); | 363 DCHECK(CalledOnValidThread()); |
| 334 DCHECK_EQ(fd, file().GetPlatformFile()); | 364 DCHECK_EQ(fd, file().GetPlatformFile()); |
| 335 | 365 |
| 336 if (pending_write_buffer()) { | 366 if (pending_write_buffer()) { |
| 337 int bytes_written = HANDLE_EINTR(write(file().GetPlatformFile(), | 367 int bytes_written = HANDLE_EINTR(write(file().GetPlatformFile(), |
| 338 pending_write_buffer(), | 368 pending_write_buffer(), |
| 339 pending_write_buffer_len())); | 369 pending_write_buffer_len())); |
| 340 if (bytes_written < 0) { | 370 if (bytes_written < 0) { |
| 341 WriteCompleted(0, serial::SendError::SYSTEM_ERROR); | 371 WriteCompleted(0, serial::SendError::SYSTEM_ERROR); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 612 memcpy(buffer, chars_stashed_, std::min(new_bytes_read, 2)); | 642 memcpy(buffer, chars_stashed_, std::min(new_bytes_read, 2)); |
| 613 memcpy(chars_stashed_, tmp, num_chars_stashed_); | 643 memcpy(chars_stashed_, tmp, num_chars_stashed_); |
| 614 return new_bytes_read; | 644 return new_bytes_read; |
| 615 } | 645 } |
| 616 | 646 |
| 617 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { | 647 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { |
| 618 return port_name; | 648 return port_name; |
| 619 } | 649 } |
| 620 | 650 |
| 621 } // namespace device | 651 } // namespace device |
| OLD | NEW |