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

Side by Side Diff: device/serial/data_pipe_producer.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: 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_pipe_producer.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "device/serial/async_waiter.h"
10
11 namespace device {
12
13 class DataPipeProducer::Buffer : public WritableBuffer {
14 public:
15 Buffer(scoped_refptr<DataPipeProducer> pipe,
16 char* buffer,
17 uint32_t buffer_size);
18 virtual ~Buffer();
19 virtual char* GetData() OVERRIDE;
20 virtual uint32_t GetSize() OVERRIDE;
21 virtual void Done(uint32_t bytes_produced) OVERRIDE;
22 virtual void DoneWithError(uint32_t bytes_produced, int32_t error) OVERRIDE;
23
24 private:
25 scoped_refptr<DataPipeProducer> pipe_;
26 char* buffer_;
27 uint32_t buffer_size_;
28 };
29
30 DataPipeProducer::DataPipeProducer(const ReadyCallback& ready_callback,
31 const ErrorCallback& error_callback)
32 : ready_callback_(ready_callback),
33 error_callback_(error_callback),
34 state_(STATE_UNINITIALIZED),
35 bytes_since_last_error_(0) {
36 }
37
38 void DataPipeProducer::Shutdown() {
39 state_ = STATE_SHUT_DOWN;
40 waiter_.reset();
41 }
42
43 DataPipeProducer::~DataPipeProducer() {
44 }
45
46 void DataPipeProducer::Init(mojo::ScopedDataPipeProducerHandle handle) {
47 if (state_ != STATE_UNINITIALIZED)
48 return;
raymes 2014/08/05 06:26:44 It might be good to DCHECK at the start of every f
Sam McNally 2014/08/05 07:26:33 Init and Resume are in response to client calls so
49
50 handle_ = handle.Pass();
51 StartWaiting();
52 }
53
54 void DataPipeProducer::Resume() {
55 if (state_ != STATE_PAUSED)
56 return;
57
58 StartWaiting();
59 }
60
61 void DataPipeProducer::OnConnectionError() {
62 HandleMojoResult(MOJO_RESULT_CANCELLED);
63 }
64
65 void DataPipeProducer::StartWaiting() {
66 state_ = STATE_WAITING_FOR_SPACE;
67 waiter_.reset(
68 new AsyncWaiter(handle_.get(),
69 MOJO_HANDLE_SIGNAL_WRITABLE,
70 base::Bind(&DataPipeProducer::OnDoneWaiting, this)));
71 }
72
73 void DataPipeProducer::OnDoneWaiting(MojoResult result) {
74 if (state_ != STATE_WAITING_FOR_SPACE || !HandleMojoResult(result))
75 return;
76 void* data = NULL;
77 uint32_t num_bytes = std::numeric_limits<uint32_t>::max();
78 result = mojo::BeginWriteDataRaw(
79 handle_.get(), &data, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
80 if (!HandleMojoResult(result))
81 return;
82 state_ = STATE_WAITING_FOR_BUFFER;
83 ready_callback_.Run(scoped_ptr<WritableBuffer>(
84 new Buffer(this, static_cast<char*>(data), num_bytes)));
85 }
86
87 void DataPipeProducer::Done(uint32_t bytes_produced) {
88 bytes_since_last_error_ += bytes_produced;
89 MojoResult result = mojo::EndWriteDataRaw(handle_.get(), bytes_produced);
90 if (!HandleMojoResult(result))
91 return;
92 if (state_ == STATE_WAITING_FOR_BUFFER)
93 StartWaiting();
94 }
95
96 void DataPipeProducer::DoneWithError(uint32_t bytes_produced, int32_t error) {
97 if (state_ == STATE_WAITING_FOR_BUFFER)
98 state_ = STATE_PAUSED;
99 Done(bytes_produced);
100 client()->OnError(bytes_since_last_error_, error);
101 bytes_since_last_error_ = 0;
102 }
103
104 bool DataPipeProducer::HandleMojoResult(MojoResult result) {
105 if (result == MOJO_RESULT_OK)
106 return true;
107
108 if (state_ == STATE_SHUT_DOWN)
109 return false;
110
111 Shutdown();
112 if (!error_callback_.is_null())
113 error_callback_.Run();
114 return false;
115 }
116
117 DataPipeProducer::Buffer::Buffer(scoped_refptr<DataPipeProducer> pipe,
118 char* buffer,
119 uint32_t buffer_size)
120 : pipe_(pipe), buffer_(buffer), buffer_size_(buffer_size) {
121 }
122
123 DataPipeProducer::Buffer::~Buffer() {
124 if (pipe_)
125 pipe_->Done(0);
126 }
127
128 char* DataPipeProducer::Buffer::GetData() {
129 return buffer_;
130 }
131
132 uint32_t DataPipeProducer::Buffer::GetSize() {
133 return buffer_size_;
134 }
135
136 void DataPipeProducer::Buffer::Done(uint32_t bytes_produced) {
137 DCHECK(pipe_);
138 pipe_->Done(bytes_produced);
139 pipe_ = NULL;
140 buffer_ = NULL;
141 buffer_size_ = 0;
142 }
143
144 void DataPipeProducer::Buffer::DoneWithError(uint32_t bytes_produced,
145 int32_t error) {
146 DCHECK(pipe_);
147 pipe_->DoneWithError(bytes_produced, error);
148 pipe_ = NULL;
149 buffer_ = NULL;
150 buffer_size_ = 0;
151 }
152
153 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698