103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file. 403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef DEVICE_SERIAL_DATA_SENDER_H_ 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define DEVICE_SERIAL_DATA_SENDER_H_ 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <queue> 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/callback.h" 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/linked_ptr.h" 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/strings/string_piece.h" 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/serial/buffer.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "device/serial/data_stream.mojom.h" 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "mojo/public/cpp/system/data_pipe.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace device { 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class AsyncWaiter; 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// A DataSender sends data to a DataSink. 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class DataSender : public serial::DataSinkClient, public mojo::ErrorHandler { 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public: 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) typedef base::Callback<void(uint32_t bytes_sent)> DataSentCallback; 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) typedef base::Callback<void(uint32_t bytes_sent, int32_t error)> 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SendErrorCallback; 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) typedef base::Callback<void()> CancelCallback; 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Constructs a DataSender to send data to |sink|, using a data pipe with a 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // buffer size of |buffer_size|, with connection errors reported as 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |fatal_error_value|. 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataSender(mojo::InterfacePtr<serial::DataSink> sink, 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint32_t buffer_size, 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int32_t fatal_error_value); 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual ~DataSender(); 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Starts an asynchronous send of |data|. If the send completes successfully, 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |callback| will be called. Otherwise, |error_callback| will be called with 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // the error. If there is a cancel in progress or there has been a connection 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // error, this will not start a send and returns false. It is the caller's 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // responsibility to ensure |data| remains valid until one of |callback| and 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // |error_callback| is called. 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool Send(const base::StringPiece& data, 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const DataSentCallback& callback, 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const SendErrorCallback& error_callback); 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Requests the cancellation of any in-progress sends. Calls to Send() will 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // fail until |callback| is called. 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool Cancel(int32_t error, const CancelCallback& callback); 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private: 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) class PendingSend; 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // serial::DataSinkClient overrides. 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual void ReportBytesSent(uint32_t bytes_sent) OVERRIDE; 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual void ReportBytesSentAndError( 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint32_t bytes_sent, 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int32_t error, 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const mojo::Callback<void(uint32_t)>& callback) OVERRIDE; 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // mojo::ErrorHandler override. 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual void OnConnectionError() OVERRIDE; 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Copies data from |pending_sends_| into the data pipe and starts |waiter_| 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // waiting if the pipe is full. When a PendingSend in |pending_sends_| has 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // been fully copied into the data pipe, it moves to |sends_awaiting_ack_|. 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void SendInternal(); 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Invoked when |handle_| is ready for writes. Calls SendInternal(). 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void OnDoneWaiting(MojoResult result); 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Dispatches a cancel callback if one is pending. 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void RunCancelCallback(); 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Shuts down this DataSender and dispatches fatal errors to all pending 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // operations. 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void ShutDown(); 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The control connection to the data sink. 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) mojo::InterfacePtr<serial::DataSink> sink_; 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The data connection to the data sink. 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) mojo::ScopedDataPipeProducerHandle handle_; 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The error value to report in the event of a fatal error. 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const int32_t fatal_error_value_; 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A waiter used to wait until |handle_| is writable if we are waiting. 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<AsyncWaiter> waiter_; 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A queue of PendingSend that have not yet been fully written to the data 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // pipe. 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::queue<linked_ptr<PendingSend> > pending_sends_; 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A queue of PendingSend that have been written to the data pipe, but have 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // not yet been acked by the DataSink. 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::queue<linked_ptr<PendingSend> > sends_awaiting_ack_; 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // The callback to report cancel completion if a cancel operation is in 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // progress. 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CancelCallback pending_cancel_; 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Whether we have encountered a fatal error and shut down. 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool shut_down_; 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DataSender); 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}; 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace device 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // DEVICE_SERIAL_DATA_SENDER_H_ 113