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

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_since_last_error_(0) {
38 }
39
40 void DataSourceSender::Shutdown() {
41 state_ = STATE_SHUT_DOWN;
42 waiter_.reset();
43 }
44
45 DataSourceSender::~DataSourceSender() {
46 }
47
48 void DataSourceSender::Init(mojo::ScopedDataPipeProducerHandle handle) {
49 if (state_ != STATE_UNINITIALIZED)
50 return;
51
52 handle_ = handle.Pass();
53 StartWaiting();
54 }
55
56 void DataSourceSender::Resume() {
57 if (state_ != STATE_PAUSED)
58 return;
59
60 StartWaiting();
61 }
62
63 void DataSourceSender::OnConnectionError() {
64 HandleMojoResult(MOJO_RESULT_CANCELLED);
65 }
66
67 void DataSourceSender::StartWaiting() {
68 state_ = STATE_WAITING_FOR_SPACE;
69 waiter_.reset(
70 new AsyncWaiter(handle_.get(),
71 MOJO_HANDLE_SIGNAL_WRITABLE,
72 base::Bind(&DataSourceSender::OnDoneWaiting, this)));
73 }
74
75 void DataSourceSender::OnDoneWaiting(MojoResult result) {
76 DCHECK(state_ == STATE_WAITING_FOR_SPACE || state_ == STATE_SHUT_DOWN);
77 if (state_ != STATE_WAITING_FOR_SPACE || !HandleMojoResult(result))
78 return;
79 void* data = NULL;
80 uint32_t num_bytes = std::numeric_limits<uint32_t>::max();
81 result = mojo::BeginWriteDataRaw(
82 handle_.get(), &data, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
83 if (!HandleMojoResult(result))
84 return;
85 state_ = STATE_WAITING_FOR_BUFFER;
86 ready_callback_.Run(scoped_ptr<WritableBuffer>(
87 new Buffer(this, static_cast<char*>(data), num_bytes)));
88 }
89
90 void DataSourceSender::Done(uint32_t bytes_produced) {
91 DCHECK(state_ == STATE_WAITING_FOR_BUFFER || state_ == STATE_PAUSED ||
92 state_ == STATE_SHUT_DOWN);
93 bytes_since_last_error_ += bytes_produced;
94 MojoResult result = mojo::EndWriteDataRaw(handle_.get(), bytes_produced);
95 if (!HandleMojoResult(result))
96 return;
97 if (state_ == STATE_WAITING_FOR_BUFFER)
98 StartWaiting();
99 }
100
101 void DataSourceSender::DoneWithError(uint32_t bytes_produced, int32_t error) {
102 DCHECK(state_ == STATE_WAITING_FOR_BUFFER || state_ == STATE_SHUT_DOWN);
103 if (state_ == STATE_WAITING_FOR_BUFFER)
104 state_ = STATE_PAUSED;
105 Done(bytes_produced);
106 client()->OnError(bytes_since_last_error_, error);
107 bytes_since_last_error_ = 0;
108 }
109
110 bool DataSourceSender::HandleMojoResult(MojoResult result) {
111 DCHECK(state_ != STATE_UNINITIALIZED);
112 if (result == MOJO_RESULT_OK)
113 return true;
114
115 if (state_ == STATE_SHUT_DOWN)
116 return false;
117
118 Shutdown();
119 if (!error_callback_.is_null())
120 error_callback_.Run();
121 return false;
122 }
123
124 DataSourceSender::Buffer::Buffer(scoped_refptr<DataSourceSender> pipe,
125 char* buffer,
126 uint32_t buffer_size)
127 : pipe_(pipe), buffer_(buffer), buffer_size_(buffer_size) {
128 }
129
130 DataSourceSender::Buffer::~Buffer() {
131 if (pipe_)
132 pipe_->Done(0);
133 }
134
135 char* DataSourceSender::Buffer::GetData() {
136 return buffer_;
137 }
138
139 uint32_t DataSourceSender::Buffer::GetSize() {
140 return buffer_size_;
141 }
142
143 void DataSourceSender::Buffer::Done(uint32_t bytes_produced) {
144 DCHECK(pipe_);
145 pipe_->Done(bytes_produced);
146 pipe_ = NULL;
147 buffer_ = NULL;
148 buffer_size_ = 0;
149 }
150
151 void DataSourceSender::Buffer::DoneWithError(uint32_t bytes_produced,
152 int32_t error) {
153 DCHECK(pipe_);
154 pipe_->DoneWithError(bytes_produced, error);
155 pipe_ = NULL;
156 buffer_ = NULL;
157 buffer_size_ = 0;
158 }
159
160 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698