Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1063)

Side by Side Diff: device/serial/data_sender.cc

Issue 2410743002: Remove the mojo serial interfaces and related infrastructure. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/serial/data_sender.h ('k') | device/serial/data_sink_receiver.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "device/serial/data_sender.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread_task_runner_handle.h"
14
15 namespace device {
16
17 // Represents a send that is not yet fulfilled.
18 class DataSender::PendingSend {
19 public:
20 PendingSend(const base::StringPiece& data,
21 const DataSentCallback& callback,
22 const SendErrorCallback& error_callback,
23 DataSender* sender);
24
25 // Reports |fatal_error_value_| to |receive_error_callback_|.
26 void DispatchFatalError();
27
28 // Attempts to send any data not yet sent to |sink|.
29 void SendData();
30
31 private:
32 // Invoked to report that |num_bytes| of data have been sent and then an
33 // error, |error| was encountered. Subtracts the number of bytes that were
34 // part of this send from |num_bytes|. If this send was not completed before
35 // the error, this calls |error_callback_| to report the error. Otherwise,
36 // this calls |callback_|. Returns the number of bytes sent but not acked.
37 void OnDataSent(uint32_t num_bytes, int32_t error);
38
39 // The data to send.
40 const base::StringPiece data_;
41
42 // The callback to report success.
43 const DataSentCallback callback_;
44
45 // The callback to report errors.
46 const SendErrorCallback error_callback_;
47
48 // The DataSender that owns this PendingSend.
49 DataSender* sender_;
50 };
51
52 DataSender::DataSender(mojo::InterfacePtr<serial::DataSink> sink,
53 uint32_t buffer_size,
54 int32_t fatal_error_value)
55 : sink_(std::move(sink)),
56 fatal_error_value_(fatal_error_value),
57 shut_down_(false) {
58 sink_.set_connection_error_handler(
59 base::Bind(&DataSender::OnConnectionError, base::Unretained(this)));
60 }
61
62 DataSender::~DataSender() {
63 ShutDown();
64 }
65
66 bool DataSender::Send(const base::StringPiece& data,
67 const DataSentCallback& callback,
68 const SendErrorCallback& error_callback) {
69 DCHECK(!callback.is_null() && !error_callback.is_null());
70 if (!pending_cancel_.is_null() || shut_down_)
71 return false;
72
73 linked_ptr<PendingSend> pending_send(
74 new PendingSend(data, callback, error_callback, this));
75 pending_send->SendData();
76 sends_awaiting_ack_.push(pending_send);
77 return true;
78 }
79
80 bool DataSender::Cancel(int32_t error, const CancelCallback& callback) {
81 DCHECK(!callback.is_null());
82 if (!pending_cancel_.is_null() || shut_down_)
83 return false;
84 if (sends_awaiting_ack_.empty()) {
85 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
86 return true;
87 }
88
89 pending_cancel_ = callback;
90 sink_->Cancel(error);
91 return true;
92 }
93
94 void DataSender::SendComplete() {
95 if (shut_down_)
96 return;
97
98 DCHECK(!sends_awaiting_ack_.empty());
99 sends_awaiting_ack_.pop();
100 if (sends_awaiting_ack_.empty())
101 RunCancelCallback();
102 }
103
104 void DataSender::SendFailed(int32_t error) {
105 if (shut_down_)
106 return;
107
108 DCHECK(!sends_awaiting_ack_.empty());
109 sends_awaiting_ack_.pop();
110 if (!sends_awaiting_ack_.empty())
111 return;
112 sink_->ClearError();
113 RunCancelCallback();
114 }
115
116 void DataSender::OnConnectionError() {
117 ShutDown();
118 }
119
120 void DataSender::RunCancelCallback() {
121 DCHECK(sends_awaiting_ack_.empty());
122 if (pending_cancel_.is_null())
123 return;
124
125 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, pending_cancel_);
126 pending_cancel_.Reset();
127 }
128
129 void DataSender::ShutDown() {
130 shut_down_ = true;
131 while (!sends_awaiting_ack_.empty()) {
132 sends_awaiting_ack_.front()->DispatchFatalError();
133 sends_awaiting_ack_.pop();
134 }
135 RunCancelCallback();
136 }
137
138 DataSender::PendingSend::PendingSend(const base::StringPiece& data,
139 const DataSentCallback& callback,
140 const SendErrorCallback& error_callback,
141 DataSender* sender)
142 : data_(data),
143 callback_(callback),
144 error_callback_(error_callback),
145 sender_(sender) {
146 }
147
148 void DataSender::PendingSend::OnDataSent(uint32_t num_bytes, int32_t error) {
149 if (error) {
150 base::ThreadTaskRunnerHandle::Get()->PostTask(
151 FROM_HERE, base::Bind(error_callback_, num_bytes, error));
152 sender_->SendFailed(error);
153 } else {
154 DCHECK(num_bytes == data_.size());
155 base::ThreadTaskRunnerHandle::Get()->PostTask(
156 FROM_HERE, base::Bind(callback_, num_bytes));
157 sender_->SendComplete();
158 }
159 }
160
161 void DataSender::PendingSend::DispatchFatalError() {
162 base::ThreadTaskRunnerHandle::Get()->PostTask(
163 FROM_HERE, base::Bind(error_callback_, 0, sender_->fatal_error_value_));
164 }
165
166 void DataSender::PendingSend::SendData() {
167 uint32_t num_bytes_to_send = static_cast<uint32_t>(data_.size());
168 mojo::Array<uint8_t> bytes(num_bytes_to_send);
169 memcpy(&bytes[0], data_.data(), num_bytes_to_send);
170 sender_->sink_->OnData(
171 std::move(bytes),
172 base::Bind(&DataSender::PendingSend::OnDataSent, base::Unretained(this)));
173 }
174
175 } // namespace device
OLDNEW
« no previous file with comments | « device/serial/data_sender.h ('k') | device/serial/data_sink_receiver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698