diff options
author | juncai <juncai@chromium.org> | 2015-07-07 12:08:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-07 19:08:45 +0000 |
commit | 3dfe209264f1d5c250c19788f259954d670ad35a (patch) | |
tree | 594112eb6f2c0775de98fd7fcd5859456efdee37 /device | |
parent | 96e46f32df8d9a3d3e62a1c588bb71345386135a (diff) | |
download | chromium_src-3dfe209264f1d5c250c19788f259954d670ad35a.zip chromium_src-3dfe209264f1d5c250c19788f259954d670ad35a.tar.gz chromium_src-3dfe209264f1d5c250c19788f259954d670ad35a.tar.bz2 |
Chrome serial device reconnect detection
For devices using CDC-ACM driver, when device is
connected, SerialIoHandler::Read and
SerialIoHandler::Write are called, when the device
is disconnected, no matching
SerialIoHandler::ReadCompleted and
SerialIoHandler::WriteCompleted are called, causing
the SerialIoHandler's refcnt to be incorrect. This
causes Chrome not to be able to release the
SerialIoHandler assigned to the device and Chrome
still thinks the device is connected, and Windows
registry entry is not updated. When the serial device
is connected again, it can not be enumerated.
This patch adds code to call SerialIoHandler::WriteCompleted;
also call SerialIoHandler::CancelRead if there is
read pending.
BUG=361606
Review URL: https://codereview.chromium.org/1229433003
Cr-Commit-Position: refs/heads/master@{#337659}
Diffstat (limited to 'device')
-rw-r--r-- | device/serial/serial_io_handler.cc | 15 | ||||
-rw-r--r-- | device/serial/serial_io_handler.h | 6 | ||||
-rw-r--r-- | device/serial/serial_io_handler_win.cc | 25 |
3 files changed, 13 insertions, 33 deletions
diff --git a/device/serial/serial_io_handler.cc b/device/serial/serial_io_handler.cc index 5300597..4a244b1 100644 --- a/device/serial/serial_io_handler.cc +++ b/device/serial/serial_io_handler.cc @@ -191,21 +191,6 @@ void SerialIoHandler::WriteCompleted(int bytes_written, Release(); } -void SerialIoHandler::ReadWriteSystemError() { - DCHECK(CalledOnValidThread()); - - DCHECK(IsWritePending()); - scoped_ptr<ReadOnlyBuffer> pending_write_buffer = - pending_write_buffer_.Pass(); - pending_write_buffer->DoneWithError(0, serial::SEND_ERROR_SYSTEM_ERROR); - - DCHECK(IsReadPending()); - scoped_ptr<WritableBuffer> pending_read_buffer = pending_read_buffer_.Pass(); - pending_read_buffer->DoneWithError(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); - - Release(); -} - bool SerialIoHandler::IsReadPending() const { DCHECK(CalledOnValidThread()); return pending_read_buffer_ != NULL; diff --git a/device/serial/serial_io_handler.h b/device/serial/serial_io_handler.h index 458d09f..bd8255e 100644 --- a/device/serial/serial_io_handler.h +++ b/device/serial/serial_io_handler.h @@ -139,12 +139,6 @@ class SerialIoHandler : public base::NonThreadSafe, // if the associated I/O operation was the only thing keeping it alive. void WriteCompleted(int bytes_written, serial::SendError error); - // Called by the implementation to signal that the device is disconnected in a - // write_context_, and also send a serial::OnReceiveError - // WARNING: Calling this method may destroy the SerialIoHandler instance - // if the associated I/O operation was the only thing keeping it alive. - void ReadWriteSystemError(); - // Queues a ReadCompleted call on the current thread. This is used to allow // ReadImpl to immediately signal completion with 0 bytes and an error, // without being reentrant. diff --git a/device/serial/serial_io_handler_win.cc b/device/serial/serial_io_handler_win.cc index 48091cc..eee5e03 100644 --- a/device/serial/serial_io_handler_win.cc +++ b/device/serial/serial_io_handler_win.cc @@ -322,18 +322,19 @@ void SerialIoHandlerWin::OnIOCompleted( if (write_canceled()) { WriteCompleted(0, write_cancel_reason()); } else if (error != ERROR_SUCCESS && error != ERROR_OPERATION_ABORTED) { - // For devices using drivers such as FTDI, CP2xxx, when device is - // disconnected, the context is comm_context_ and the error is - // ERROR_OPERATION_ABORTED. - // However, for devices using CDC-ACM driver, when device is disconnected, - // the context is write_context_ and the error is ERROR_GEN_FAILURE. In - // this situation, in addition to a write error signal, also need to - // generate a read error signal serial::OnReceiveError which will notify - // the app about the disconnection. - if (error == ERROR_GEN_FAILURE) - ReadWriteSystemError(); - else - WriteCompleted(0, serial::SEND_ERROR_SYSTEM_ERROR); + WriteCompleted(0, serial::SEND_ERROR_SYSTEM_ERROR); + if (error == ERROR_GEN_FAILURE && IsReadPending()) { + // For devices using drivers such as FTDI, CP2xxx, when device is + // disconnected, the context is comm_context_ and the error is + // ERROR_OPERATION_ABORTED. + // However, for devices using CDC-ACM driver, when device is + // disconnected, the context is write_context_ and the error is + // ERROR_GEN_FAILURE. In this situation, in addition to a write error + // signal, also need to generate a read error signal + // serial::OnReceiveError which will notify the app about the + // disconnection. + CancelRead(serial::RECEIVE_ERROR_SYSTEM_ERROR); + } } else { WriteCompleted(bytes_transferred, error == ERROR_SUCCESS ? serial::SEND_ERROR_NONE |