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 3// found in the LICENSE file. 4 5#ifndef DEVICE_SERIAL_DATA_SENDER_H_ 6#define DEVICE_SERIAL_DATA_SENDER_H_ 7 8#include <queue> 9 10#include "base/callback.h" 11#include "base/memory/linked_ptr.h" 12#include "base/strings/string_piece.h" 13#include "device/serial/buffer.h" 14#include "device/serial/data_stream.mojom.h" 15#include "mojo/public/cpp/system/data_pipe.h" 16 17namespace device { 18 19class AsyncWaiter; 20 21// A DataSender sends data to a DataSink. 22class DataSender : public serial::DataSinkClient, public mojo::ErrorHandler { 23 public: 24 typedef base::Callback<void(uint32_t bytes_sent)> DataSentCallback; 25 typedef base::Callback<void(uint32_t bytes_sent, int32_t error)> 26 SendErrorCallback; 27 typedef base::Callback<void()> CancelCallback; 28 29 // Constructs a DataSender to send data to |sink|, using a data pipe with a 30 // buffer size of |buffer_size|, with connection errors reported as 31 // |fatal_error_value|. 32 DataSender(mojo::InterfacePtr<serial::DataSink> sink, 33 uint32_t buffer_size, 34 int32_t fatal_error_value); 35 36 virtual ~DataSender(); 37 38 // Starts an asynchronous send of |data|. If the send completes successfully, 39 // |callback| will be called. Otherwise, |error_callback| will be called with 40 // the error. If there is a cancel in progress or there has been a connection 41 // error, this will not start a send and returns false. It is the caller's 42 // responsibility to ensure |data| remains valid until one of |callback| and 43 // |error_callback| is called. 44 bool Send(const base::StringPiece& data, 45 const DataSentCallback& callback, 46 const SendErrorCallback& error_callback); 47 48 // Requests the cancellation of any in-progress sends. Calls to Send() will 49 // fail until |callback| is called. 50 bool Cancel(int32_t error, const CancelCallback& callback); 51 52 private: 53 class PendingSend; 54 55 // serial::DataSinkClient overrides. 56 virtual void ReportBytesSent(uint32_t bytes_sent) OVERRIDE; 57 virtual void ReportBytesSentAndError( 58 uint32_t bytes_sent, 59 int32_t error, 60 const mojo::Callback<void(uint32_t)>& callback) OVERRIDE; 61 62 // mojo::ErrorHandler override. 63 virtual void OnConnectionError() OVERRIDE; 64 65 // Copies data from |pending_sends_| into the data pipe and starts |waiter_| 66 // waiting if the pipe is full. When a PendingSend in |pending_sends_| has 67 // been fully copied into the data pipe, it moves to |sends_awaiting_ack_|. 68 void SendInternal(); 69 70 // Invoked when |handle_| is ready for writes. Calls SendInternal(). 71 void OnDoneWaiting(MojoResult result); 72 73 // Dispatches a cancel callback if one is pending. 74 void RunCancelCallback(); 75 76 // Shuts down this DataSender and dispatches fatal errors to all pending 77 // operations. 78 void ShutDown(); 79 80 // The control connection to the data sink. 81 mojo::InterfacePtr<serial::DataSink> sink_; 82 83 // The data connection to the data sink. 84 mojo::ScopedDataPipeProducerHandle handle_; 85 86 // The error value to report in the event of a fatal error. 87 const int32_t fatal_error_value_; 88 89 // A waiter used to wait until |handle_| is writable if we are waiting. 90 scoped_ptr<AsyncWaiter> waiter_; 91 92 // A queue of PendingSend that have not yet been fully written to the data 93 // pipe. 94 std::queue<linked_ptr<PendingSend> > pending_sends_; 95 96 // A queue of PendingSend that have been written to the data pipe, but have 97 // not yet been acked by the DataSink. 98 std::queue<linked_ptr<PendingSend> > sends_awaiting_ack_; 99 100 // The callback to report cancel completion if a cancel operation is in 101 // progress. 102 CancelCallback pending_cancel_; 103 104 // Whether we have encountered a fatal error and shut down. 105 bool shut_down_; 106 107 DISALLOW_COPY_AND_ASSIGN(DataSender); 108}; 109 110} // namespace device 111 112#endif // DEVICE_SERIAL_DATA_SENDER_H_ 113