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

Side by Side Diff: mojo/system/local_data_pipe.cc

Issue 118873004: Mojo: DataPipe: Write some docs and rationalize some return values. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review fixes Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « mojo/public/system/core.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // TODO(vtl): I currently potentially overflow in doing index calculations. 5 // TODO(vtl): I currently potentially overflow in doing index calculations.
6 // E.g., |start_index_| and |current_num_bytes_| fit into a |uint32_t|, but 6 // E.g., |start_index_| and |current_num_bytes_| fit into a |uint32_t|, but
7 // their sum may not. This is bad and poses a security risk. (We're currently 7 // their sum may not. This is bad and poses a security risk. (We're currently
8 // saved by the limit on capacity -- the maximum size of the buffer, checked in 8 // saved by the limit on capacity -- the maximum size of the buffer, checked in
9 // |DataPipe::ValidateOptions()|, is currently sufficiently small. 9 // |DataPipe::ValidateOptions()|, is currently sufficiently small.
10 10
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 DestroyBufferNoLock(); 43 DestroyBufferNoLock();
44 } 44 }
45 AwakeConsumerWaitersForStateChangeNoLock(); 45 AwakeConsumerWaitersForStateChangeNoLock();
46 } 46 }
47 47
48 MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements, 48 MojoResult LocalDataPipe::ProducerWriteDataImplNoLock(const void* elements,
49 uint32_t* num_bytes, 49 uint32_t* num_bytes,
50 bool all_or_none) { 50 bool all_or_none) {
51 DCHECK_EQ(*num_bytes % element_num_bytes(), 0u); 51 DCHECK_EQ(*num_bytes % element_num_bytes(), 0u);
52 DCHECK_GT(*num_bytes, 0u); 52 DCHECK_GT(*num_bytes, 0u);
53 DCHECK(consumer_open_no_lock());
53 54
54 size_t num_bytes_to_write = 0; 55 size_t num_bytes_to_write = 0;
55 if (may_discard()) { 56 if (may_discard()) {
56 if (all_or_none && *num_bytes > capacity_num_bytes()) 57 if (all_or_none && *num_bytes > capacity_num_bytes())
57 return MOJO_RESULT_OUT_OF_RANGE; 58 return MOJO_RESULT_OUT_OF_RANGE;
58 59
59 num_bytes_to_write = std::min(static_cast<size_t>(*num_bytes), 60 num_bytes_to_write = std::min(static_cast<size_t>(*num_bytes),
60 capacity_num_bytes()); 61 capacity_num_bytes());
61 if (num_bytes_to_write > capacity_num_bytes() - current_num_bytes_) { 62 if (num_bytes_to_write > capacity_num_bytes() - current_num_bytes_) {
62 // Discard as much as needed (discard oldest first). 63 // Discard as much as needed (discard oldest first).
63 size_t num_bytes_to_discard = 64 size_t num_bytes_to_discard =
64 num_bytes_to_write - (capacity_num_bytes() - current_num_bytes_); 65 num_bytes_to_write - (capacity_num_bytes() - current_num_bytes_);
65 start_index_ += num_bytes_to_discard; 66 start_index_ += num_bytes_to_discard;
66 start_index_ %= capacity_num_bytes(); 67 start_index_ %= capacity_num_bytes();
67 current_num_bytes_ -= num_bytes_to_discard; 68 current_num_bytes_ -= num_bytes_to_discard;
68 } 69 }
69 } else { 70 } else {
70 if (all_or_none && *num_bytes > capacity_num_bytes() - current_num_bytes_) { 71 if (all_or_none && *num_bytes > capacity_num_bytes() - current_num_bytes_) {
71 return (*num_bytes > capacity_num_bytes()) ? MOJO_RESULT_OUT_OF_RANGE : 72 // Don't return "should wait" since you can't wait for a specified amount
72 MOJO_RESULT_SHOULD_WAIT; 73 // of data.
74 return MOJO_RESULT_OUT_OF_RANGE;
73 } 75 }
74 76
75 num_bytes_to_write = std::min(static_cast<size_t>(*num_bytes), 77 num_bytes_to_write = std::min(static_cast<size_t>(*num_bytes),
76 capacity_num_bytes() - current_num_bytes_); 78 capacity_num_bytes() - current_num_bytes_);
77 } 79 }
78 if (num_bytes_to_write == 0) 80 if (num_bytes_to_write == 0)
79 return MOJO_RESULT_SHOULD_WAIT; 81 return MOJO_RESULT_SHOULD_WAIT;
80 82
81 // The amount we can write in our first |memcpy()|. 83 // The amount we can write in our first |memcpy()|.
82 size_t num_bytes_to_write_first = 84 size_t num_bytes_to_write_first =
(...skipping 20 matching lines...) Expand all
103 AwakeConsumerWaitersForStateChangeNoLock(); 105 AwakeConsumerWaitersForStateChangeNoLock();
104 106
105 *num_bytes = static_cast<uint32_t>(num_bytes_to_write); 107 *num_bytes = static_cast<uint32_t>(num_bytes_to_write);
106 return MOJO_RESULT_OK; 108 return MOJO_RESULT_OK;
107 } 109 }
108 110
109 MojoResult LocalDataPipe::ProducerBeginWriteDataImplNoLock( 111 MojoResult LocalDataPipe::ProducerBeginWriteDataImplNoLock(
110 void** buffer, 112 void** buffer,
111 uint32_t* buffer_num_bytes, 113 uint32_t* buffer_num_bytes,
112 bool all_or_none) { 114 bool all_or_none) {
115 DCHECK(consumer_open_no_lock());
116
113 size_t max_num_bytes_to_write = GetMaxNumBytesToWriteNoLock(); 117 size_t max_num_bytes_to_write = GetMaxNumBytesToWriteNoLock();
114 // TODO(vtl): Consider this return value. 118 if (all_or_none && *buffer_num_bytes > max_num_bytes_to_write) {
115 if (all_or_none && *buffer_num_bytes > max_num_bytes_to_write) 119 // Don't return "should wait" since you can't wait for a specified amount of
120 // data.
116 return MOJO_RESULT_OUT_OF_RANGE; 121 return MOJO_RESULT_OUT_OF_RANGE;
122 }
117 123
118 // Don't go into a two-phase write if there's no room. 124 // Don't go into a two-phase write if there's no room.
119 if (max_num_bytes_to_write == 0) 125 if (max_num_bytes_to_write == 0)
120 return MOJO_RESULT_SHOULD_WAIT; 126 return MOJO_RESULT_SHOULD_WAIT;
121 127
122 size_t write_index = 128 size_t write_index =
123 (start_index_ + current_num_bytes_) % capacity_num_bytes(); 129 (start_index_ + current_num_bytes_) % capacity_num_bytes();
124 EnsureBufferNoLock(); 130 EnsureBufferNoLock();
125 *buffer = buffer_.get() + write_index; 131 *buffer = buffer_.get() + write_index;
126 *buffer_num_bytes = static_cast<uint32_t>(max_num_bytes_to_write); 132 *buffer_num_bytes = static_cast<uint32_t>(max_num_bytes_to_write);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 current_num_bytes_ = 0; 178 current_num_bytes_ = 0;
173 AwakeProducerWaitersForStateChangeNoLock(); 179 AwakeProducerWaitersForStateChangeNoLock();
174 } 180 }
175 181
176 MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements, 182 MojoResult LocalDataPipe::ConsumerReadDataImplNoLock(void* elements,
177 uint32_t* num_bytes, 183 uint32_t* num_bytes,
178 bool all_or_none) { 184 bool all_or_none) {
179 DCHECK_EQ(*num_bytes % element_num_bytes(), 0u); 185 DCHECK_EQ(*num_bytes % element_num_bytes(), 0u);
180 DCHECK_GT(*num_bytes, 0u); 186 DCHECK_GT(*num_bytes, 0u);
181 187
182 // TODO(vtl): Think about the error code in this case. 188 if (all_or_none && *num_bytes > current_num_bytes_) {
183 if (all_or_none && *num_bytes > current_num_bytes_) 189 // Don't return "should wait" since you can't wait for a specified amount of
184 return MOJO_RESULT_OUT_OF_RANGE; 190 // data.
191 return producer_open_no_lock() ? MOJO_RESULT_OUT_OF_RANGE :
192 MOJO_RESULT_FAILED_PRECONDITION;
193 }
185 194
186 size_t num_bytes_to_read = 195 size_t num_bytes_to_read =
187 std::min(static_cast<size_t>(*num_bytes), current_num_bytes_); 196 std::min(static_cast<size_t>(*num_bytes), current_num_bytes_);
188 if (num_bytes_to_read == 0) { 197 if (num_bytes_to_read == 0) {
189 return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT : 198 return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT :
190 MOJO_RESULT_FAILED_PRECONDITION; 199 MOJO_RESULT_FAILED_PRECONDITION;
191 } 200 }
192 201
193 // The amount we can read in our first |memcpy()|. 202 // The amount we can read in our first |memcpy()|.
194 size_t num_bytes_to_read_first = 203 size_t num_bytes_to_read_first =
(...skipping 18 matching lines...) Expand all
213 222
214 *num_bytes = static_cast<uint32_t>(num_bytes_to_read); 223 *num_bytes = static_cast<uint32_t>(num_bytes_to_read);
215 return MOJO_RESULT_OK; 224 return MOJO_RESULT_OK;
216 } 225 }
217 226
218 MojoResult LocalDataPipe::ConsumerDiscardDataImplNoLock(uint32_t* num_bytes, 227 MojoResult LocalDataPipe::ConsumerDiscardDataImplNoLock(uint32_t* num_bytes,
219 bool all_or_none) { 228 bool all_or_none) {
220 DCHECK_EQ(*num_bytes % element_num_bytes(), 0u); 229 DCHECK_EQ(*num_bytes % element_num_bytes(), 0u);
221 DCHECK_GT(*num_bytes, 0u); 230 DCHECK_GT(*num_bytes, 0u);
222 231
223 // TODO(vtl): Think about the error code in this case. 232 if (all_or_none && *num_bytes > current_num_bytes_) {
224 if (all_or_none && *num_bytes > current_num_bytes_) 233 // Don't return "should wait" since you can't wait for a specified amount of
225 return MOJO_RESULT_OUT_OF_RANGE; 234 // data.
235 return producer_open_no_lock() ? MOJO_RESULT_OUT_OF_RANGE :
236 MOJO_RESULT_FAILED_PRECONDITION;
237 }
226 238
227 // Be consistent with other operations; error if no data available. 239 // Be consistent with other operations; error if no data available.
228 if (current_num_bytes_ == 0) { 240 if (current_num_bytes_ == 0) {
229 return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT : 241 return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT :
230 MOJO_RESULT_FAILED_PRECONDITION; 242 MOJO_RESULT_FAILED_PRECONDITION;
231 } 243 }
232 244
233 bool was_full = (current_num_bytes_ == capacity_num_bytes()); 245 bool was_full = (current_num_bytes_ == capacity_num_bytes());
234 246
235 size_t num_bytes_to_discard = 247 size_t num_bytes_to_discard =
(...skipping 12 matching lines...) Expand all
248 // Note: This cast is safe, since the capacity fits into a |uint32_t|. 260 // Note: This cast is safe, since the capacity fits into a |uint32_t|.
249 *num_bytes = static_cast<uint32_t>(current_num_bytes_); 261 *num_bytes = static_cast<uint32_t>(current_num_bytes_);
250 return MOJO_RESULT_OK; 262 return MOJO_RESULT_OK;
251 } 263 }
252 264
253 MojoResult LocalDataPipe::ConsumerBeginReadDataImplNoLock( 265 MojoResult LocalDataPipe::ConsumerBeginReadDataImplNoLock(
254 const void** buffer, 266 const void** buffer,
255 uint32_t* buffer_num_bytes, 267 uint32_t* buffer_num_bytes,
256 bool all_or_none) { 268 bool all_or_none) {
257 size_t max_num_bytes_to_read = GetMaxNumBytesToReadNoLock(); 269 size_t max_num_bytes_to_read = GetMaxNumBytesToReadNoLock();
258 // TODO(vtl): Consider this return value. 270 if (all_or_none && *buffer_num_bytes > max_num_bytes_to_read) {
259 if (all_or_none && *buffer_num_bytes > max_num_bytes_to_read) 271 // Don't return "should wait" since you can't wait for a specified amount of
272 // data.
260 return MOJO_RESULT_OUT_OF_RANGE; 273 return MOJO_RESULT_OUT_OF_RANGE;
274 }
261 275
262 // Don't go into a two-phase read if there's no data. 276 // Don't go into a two-phase read if there's no data.
263 if (max_num_bytes_to_read == 0) { 277 if (max_num_bytes_to_read == 0) {
264 return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT : 278 return producer_open_no_lock() ? MOJO_RESULT_SHOULD_WAIT :
265 MOJO_RESULT_FAILED_PRECONDITION; 279 MOJO_RESULT_FAILED_PRECONDITION;
266 } 280 }
267 281
268 *buffer = buffer_.get() + start_index_; 282 *buffer = buffer_.get() + start_index_;
269 *buffer_num_bytes = static_cast<uint32_t>(max_num_bytes_to_read); 283 *buffer_num_bytes = static_cast<uint32_t>(max_num_bytes_to_read);
270 set_consumer_two_phase_max_num_bytes_read_no_lock( 284 set_consumer_two_phase_max_num_bytes_read_no_lock(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 } 354 }
341 355
342 size_t LocalDataPipe::GetMaxNumBytesToReadNoLock() { 356 size_t LocalDataPipe::GetMaxNumBytesToReadNoLock() {
343 if (start_index_ + current_num_bytes_ > capacity_num_bytes()) 357 if (start_index_ + current_num_bytes_ > capacity_num_bytes())
344 return capacity_num_bytes() - start_index_; 358 return capacity_num_bytes() - start_index_;
345 return current_num_bytes_; 359 return current_num_bytes_;
346 } 360 }
347 361
348 } // namespace system 362 } // namespace system
349 } // namespace mojo 363 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/system/core.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698