• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
InitializeImpl()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 
file()114   base::PlatformFile file() const {
115     return file_;
116   }
117 
pending_read_buffer()118   net::IOBuffer* pending_read_buffer() const {
119     return pending_read_buffer_.get();
120   }
121 
pending_read_buffer_len()122   int pending_read_buffer_len() const {
123     return pending_read_buffer_len_;
124   }
125 
read_cancel_reason()126   api::serial::ReceiveError read_cancel_reason() const {
127     return read_cancel_reason_;
128   }
129 
read_canceled()130   bool read_canceled() const {
131     return read_canceled_;
132   }
133 
pending_write_buffer()134   net::IOBuffer* pending_write_buffer() const {
135     return pending_write_buffer_.get();
136   }
137 
pending_write_buffer_len()138   int pending_write_buffer_len() const {
139     return pending_write_buffer_len_;
140   }
141 
write_cancel_reason()142   api::serial::SendError write_cancel_reason() const {
143     return write_cancel_reason_;
144   }
145 
write_canceled()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