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