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

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

Issue 437933002: Add data pipe wrappers to be used to implement serial receive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@serial-buffer
Patch Set: address comments Created 6 years, 4 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
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_source_sender.h"
6
7 #include <limits>
8
9 #include "base/bind.h"
10 #include "base/message_loop/message_loop.h"
11 #include "device/serial/async_waiter.h"
12
13 namespace device {
14
15 class DataSourceSender::Buffer : public WritableBuffer {
16 public:
17 Buffer(scoped_refptr<DataSourceSender> pipe,
18 char* buffer,
19 uint32_t buffer_size);
20 virtual ~Buffer();
21 virtual char* GetData() OVERRIDE;
22 virtual uint32_t GetSize() OVERRIDE;
23 virtual void Done(uint32_t bytes_produced) OVERRIDE;
24 virtual void DoneWithError(uint32_t bytes_produced, int32_t error) OVERRIDE;
25
26 private:
27 scoped_refptr<DataSourceSender> pipe_;
28 char* buffer_;
29 uint32_t buffer_size_;
30 };
31
32 DataSourceSender::DataSourceSender(const ReadyCallback& ready_callback,
33 const ErrorCallback& error_callback)
34 : ready_callback_(ready_callback),
35 error_callback_(error_callback),
36 state_(STATE_UNINITIALIZED),
37 bytes_sent_(0) {
38 DCHECK(!ready_callback.is_null() && !error_callback.is_null());
39 }
40
41 // This is part of the public interface so can be called while we are in any
42 // state.
43 void DataSourceSender::Shutdown() {
44 state_ = STATE_SHUT_DOWN;
45 waiter_.reset();
46 }
47
48 DataSourceSender::~DataSourceSender() {
49 DCHECK_EQ(state_, STATE_SHUT_DOWN);
50 }
51
52 // This is part of the DataSource interface so can be called while we are in any
53 // state.
54 void DataSourceSender::Init(mojo::ScopedDataPipeProducerHandle handle) {
55 if (state_ != STATE_UNINITIALIZED)
56 return;
57
58 handle_ = handle.Pass();
59 StartWaiting();
60 }
61
62 // This is part of the DataSource interface so can be called while we are in any
63 // state.
64 void DataSourceSender::Resume() {
65 if (state_ != STATE_PAUSED)
66 return;
67
68 StartWaiting();
69 }
70
71 // This is invoked in the case of a connection error so can be called while we
72 // are in any state.
73 void DataSourceSender::OnConnectionError() {
74 HandleMojoResult(MOJO_RESULT_CANCELLED);
75 }
76
77 void DataSourceSender::StartWaiting() {
78 state_ = STATE_WAITING_FOR_SPACE;
79 waiter_.reset(
80 new AsyncWaiter(handle_.get(),
81 MOJO_HANDLE_SIGNAL_WRITABLE,
82 base::Bind(&DataSourceSender::OnDoneWaiting, this)));
83 }
84
85 void DataSourceSender::OnDoneWaiting(MojoResult result) {
86 DCHECK(state_ == STATE_WAITING_FOR_SPACE);
87 if (!HandleMojoResult(result))
88 return;
89 void* data = NULL;
90 uint32_t num_bytes = std::numeric_limits<uint32_t>::max();
91 result = mojo::BeginWriteDataRaw(
92 handle_.get(), &data, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
93 if (!HandleMojoResult(result))
94 return;
95 state_ = STATE_WAITING_FOR_BUFFER;
96 ready_callback_.Run(scoped_ptr<WritableBuffer>(
97 new Buffer(this, static_cast<char*>(data), num_bytes)));
98 }
99
100 void DataSourceSender::Done(uint32_t bytes_produced) {
101 DCHECK(state_ == STATE_WAITING_FOR_BUFFER || state_ == STATE_PAUSED ||
102 state_ == STATE_SHUT_DOWN);
103 bytes_sent_ += bytes_produced;
104 MojoResult result = mojo::EndWriteDataRaw(handle_.get(), bytes_produced);
105 if (!HandleMojoResult(result))
106 return;
107 if (state_ == STATE_WAITING_FOR_BUFFER)
108 StartWaiting();
109 }
110
111 void DataSourceSender::DoneWithError(uint32_t bytes_produced, int32_t error) {
112 DCHECK(state_ == STATE_WAITING_FOR_BUFFER || state_ == STATE_SHUT_DOWN);
113 if (state_ == STATE_WAITING_FOR_BUFFER)
114 state_ = STATE_PAUSED;
115 Done(bytes_produced);
116 client()->OnError(bytes_sent_, error);
117 }
118
119 bool DataSourceSender::HandleMojoResult(MojoResult result) {
120 DCHECK(state_ != STATE_UNINITIALIZED);
121 if (result == MOJO_RESULT_OK)
122 return true;
123
124 if (state_ == STATE_SHUT_DOWN)
125 return false;
126
127 Shutdown();
128 error_callback_.Run();
129 return false;
130 }
131
132 DataSourceSender::Buffer::Buffer(scoped_refptr<DataSourceSender> pipe,
133 char* buffer,
134 uint32_t buffer_size)
135 : pipe_(pipe), buffer_(buffer), buffer_size_(buffer_size) {
136 }
137
138 DataSourceSender::Buffer::~Buffer() {
139 if (pipe_)
140 pipe_->Done(0);
141 }
142
143 char* DataSourceSender::Buffer::GetData() {
144 return buffer_;
145 }
146
147 uint32_t DataSourceSender::Buffer::GetSize() {
148 return buffer_size_;
149 }
150
151 void DataSourceSender::Buffer::Done(uint32_t bytes_produced) {
152 DCHECK(pipe_);
153 pipe_->Done(bytes_produced);
154 pipe_ = NULL;
155 buffer_ = NULL;
156 buffer_size_ = 0;
157 }
158
159 void DataSourceSender::Buffer::DoneWithError(uint32_t bytes_produced,
160 int32_t error) {
161 DCHECK(pipe_);
162 pipe_->DoneWithError(bytes_produced, error);
163 pipe_ = NULL;
164 buffer_ = NULL;
165 buffer_size_ = 0;
166 }
167
168 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698