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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_SERIAL_SERIAL_IO_HANDLER_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_SERIAL_SERIAL_IO_HANDLER_H_ 7 8 #include "base/callback.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/platform_file.h" 11 #include "base/threading/non_thread_safe.h" 12 #include "chrome/common/extensions/api/serial.h" 13 #include "net/base/io_buffer.h" 14 15 namespace extensions { 16 17 // Provides a simplified interface for performing asynchronous I/O on serial 18 // devices by hiding platform-specific MessageLoop interfaces. Pending I/O 19 // operations hold a reference to this object until completion so that memory 20 // doesn't disappear out from under the OS. 21 class SerialIoHandler : public base::NonThreadSafe, 22 public base::RefCounted<SerialIoHandler> { 23 public: 24 // Constructs an instance of some platform-specific subclass. 25 static scoped_refptr<SerialIoHandler> Create(); 26 27 // Called with a string of bytes read, and a result code. Note that an error 28 // result does not necessarily imply 0 bytes read. 29 typedef base::Callback<void(const std::string& data, 30 api::serial::ReceiveError error)> 31 ReadCompleteCallback; 32 33 // Called with the number of bytes written and a result code. Note that an 34 // error result does not necessarily imply 0 bytes written. 35 typedef base::Callback<void(int bytes_written, api::serial::SendError error)> 36 WriteCompleteCallback; 37 38 // Initializes the handler on the current message loop. Must be called exactly 39 // once before performing any I/O through the handler. 40 void Initialize(base::PlatformFile file, 41 const ReadCompleteCallback& read_callback, 42 const WriteCompleteCallback& write_callback); 43 44 // Performs an async Read operation. Behavior is undefined if this is called 45 // while a Read is already pending. Otherwise, the ReadCompleteCallback 46 // (see above) will eventually be called with a result. 47 void Read(int max_bytes); 48 49 // Performs an async Write operation. Behavior is undefined if this is called 50 // while a Write is already pending. Otherwise, the WriteCompleteCallback 51 // (see above) will eventually be called with a result. 52 void Write(const std::string& data); 53 54 // Indicates whether or not a read is currently pending. 55 bool IsReadPending() const; 56 57 // Indicates whether or not a write is currently pending. 58 bool IsWritePending() const; 59 60 // Attempts to cancel a pending read operation. 61 void CancelRead(api::serial::ReceiveError reason); 62 63 // Attempts to cancel a pending write operation. 64 void CancelWrite(api::serial::SendError reason); 65 66 protected: 67 SerialIoHandler(); 68 virtual ~SerialIoHandler(); 69 70 // Performs platform-specific initialization. |file_|, |read_complete_| and 71 // |write_complete_| all hold initialized values before this is called. 72 virtual void InitializeImpl() {} 73 74 // Performs a platform-specific read operation. This must guarantee that 75 // ReadCompleted is called when the underlying async operation is completed 76 // or the SerialIoHandler instance will leak. 77 // NOTE: Implementations of ReadImpl should never call ReadCompleted directly. 78 // Use QueueReadCompleted instead to avoid reentrancy. 79 virtual void ReadImpl() = 0; 80 81 // Performs a platform-specific write operation. This must guarantee that 82 // WriteCompleted is called when the underlying async operation is completed 83 // or the SerialIoHandler instance will leak. 84 // NOTE: Implementations of Writempl should never call WriteCompleted 85 // directly. Use QueueWriteCompleted instead to avoid reentrancy. 86 virtual void WriteImpl() = 0; 87 88 // Platform-specific read cancelation. 89 virtual void CancelReadImpl() = 0; 90 91 // Platform-specific write cancelation. 92 virtual void CancelWriteImpl() = 0; 93 94 // Called by the implementation to signal that the active read has completed. 95 // WARNING: Calling this method can destroy the SerialIoHandler instance 96 // if the associated I/O operation was the only thing keeping it alive. 97 void ReadCompleted(int bytes_read, api::serial::ReceiveError error); 98 99 // Called by the implementation to signal that the active write has completed. 100 // WARNING: Calling this method may destroy the SerialIoHandler instance 101 // if the associated I/O operation was the only thing keeping it alive. 102 void WriteCompleted(int bytes_written, api::serial::SendError error); 103 104 // Queues a ReadCompleted call on the current thread. This is used to allow 105 // ReadImpl to immediately signal completion with 0 bytes and an error, 106 // without being reentrant. 107 void QueueReadCompleted(int bytes_read, api::serial::ReceiveError error); 108 109 // Queues a WriteCompleted call on the current thread. This is used to allow 110 // WriteImpl to immediately signal completion with 0 bytes and an error, 111 // without being reentrant. 112 void QueueWriteCompleted(int bytes_written, api::serial::SendError error); 113 114 base::PlatformFile file() const { 115 return file_; 116 } 117 118 net::IOBuffer* pending_read_buffer() const { 119 return pending_read_buffer_.get(); 120 } 121 122 int pending_read_buffer_len() const { 123 return pending_read_buffer_len_; 124 } 125 126 api::serial::ReceiveError read_cancel_reason() const { 127 return read_cancel_reason_; 128 } 129 130 bool read_canceled() const { 131 return read_canceled_; 132 } 133 134 net::IOBuffer* pending_write_buffer() const { 135 return pending_write_buffer_.get(); 136 } 137 138 int pending_write_buffer_len() const { 139 return pending_write_buffer_len_; 140 } 141 142 api::serial::SendError write_cancel_reason() const { 143 return write_cancel_reason_; 144 } 145 146 bool write_canceled() const { 147 return write_canceled_; 148 } 149 150 private: 151 friend class base::RefCounted<SerialIoHandler>; 152 153 base::PlatformFile file_; 154 155 scoped_refptr<net::IOBuffer> pending_read_buffer_; 156 int pending_read_buffer_len_; 157 api::serial::ReceiveError read_cancel_reason_; 158 bool read_canceled_; 159 160 scoped_refptr<net::IOBuffer> pending_write_buffer_; 161 int pending_write_buffer_len_; 162 api::serial::SendError write_cancel_reason_; 163 bool write_canceled_; 164 165 ReadCompleteCallback read_complete_; 166 WriteCompleteCallback write_complete_; 167 168 DISALLOW_COPY_AND_ASSIGN(SerialIoHandler); 169 }; 170 171 } // namespace extensions 172 173 #endif // CHROME_BROWSER_EXTENSIONS_API_SERIAL_SERIAL_IO_HANDLER_H_ 174