OLD | NEW |
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 #include "mojo/system/data_pipe.h" | 5 #include "mojo/system/data_pipe.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <limits> | 10 #include <limits> |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 consumer_waiter_list_.reset(); | 223 consumer_waiter_list_.reset(); |
224 // Not a bug, except possibly in "user" code. | 224 // Not a bug, except possibly in "user" code. |
225 DVLOG_IF(2, consumer_in_two_phase_read_no_lock()) | 225 DVLOG_IF(2, consumer_in_two_phase_read_no_lock()) |
226 << "Consumer closed with active two-phase read"; | 226 << "Consumer closed with active two-phase read"; |
227 consumer_two_phase_max_num_bytes_read_ = 0; | 227 consumer_two_phase_max_num_bytes_read_ = 0; |
228 ConsumerCloseImplNoLock(); | 228 ConsumerCloseImplNoLock(); |
229 AwakeProducerWaitersForStateChangeNoLock( | 229 AwakeProducerWaitersForStateChangeNoLock( |
230 ProducerGetHandleSignalsStateNoLock()); | 230 ProducerGetHandleSignalsStateNoLock()); |
231 } | 231 } |
232 | 232 |
233 MojoResult DataPipe::ConsumerReadData(void* elements, | 233 MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements, |
234 uint32_t* num_bytes, | 234 UserPointer<uint32_t> num_bytes, |
235 bool all_or_none) { | 235 bool all_or_none) { |
236 base::AutoLock locker(lock_); | 236 base::AutoLock locker(lock_); |
237 DCHECK(has_local_consumer_no_lock()); | 237 DCHECK(has_local_consumer_no_lock()); |
238 | 238 |
239 if (consumer_in_two_phase_read_no_lock()) | 239 if (consumer_in_two_phase_read_no_lock()) |
240 return MOJO_RESULT_BUSY; | 240 return MOJO_RESULT_BUSY; |
241 | 241 |
242 if (*num_bytes % element_num_bytes_ != 0) | 242 uint32_t max_num_bytes_to_read = num_bytes.Get(); |
| 243 if (max_num_bytes_to_read % element_num_bytes_ != 0) |
243 return MOJO_RESULT_INVALID_ARGUMENT; | 244 return MOJO_RESULT_INVALID_ARGUMENT; |
244 | 245 |
245 if (*num_bytes == 0) | 246 if (max_num_bytes_to_read == 0) |
246 return MOJO_RESULT_OK; // Nothing to do. | 247 return MOJO_RESULT_OK; // Nothing to do. |
247 | 248 |
| 249 uint32_t min_num_bytes_to_read = all_or_none ? max_num_bytes_to_read : 0; |
| 250 |
248 HandleSignalsState old_producer_state = ProducerGetHandleSignalsStateNoLock(); | 251 HandleSignalsState old_producer_state = ProducerGetHandleSignalsStateNoLock(); |
249 MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, all_or_none); | 252 MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, |
| 253 max_num_bytes_to_read, |
| 254 min_num_bytes_to_read); |
250 HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock(); | 255 HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock(); |
251 if (!new_producer_state.equals(old_producer_state)) | 256 if (!new_producer_state.equals(old_producer_state)) |
252 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); | 257 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); |
253 return rv; | 258 return rv; |
254 } | 259 } |
255 | 260 |
256 MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes, | 261 MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes, |
257 bool all_or_none) { | 262 bool all_or_none) { |
258 base::AutoLock locker(lock_); | 263 base::AutoLock locker(lock_); |
259 DCHECK(has_local_consumer_no_lock()); | 264 DCHECK(has_local_consumer_no_lock()); |
260 | 265 |
261 if (consumer_in_two_phase_read_no_lock()) | 266 if (consumer_in_two_phase_read_no_lock()) |
262 return MOJO_RESULT_BUSY; | 267 return MOJO_RESULT_BUSY; |
263 | 268 |
264 if (*num_bytes % element_num_bytes_ != 0) | 269 uint32_t max_num_bytes_to_discard = num_bytes.Get(); |
| 270 if (max_num_bytes_to_discard % element_num_bytes_ != 0) |
265 return MOJO_RESULT_INVALID_ARGUMENT; | 271 return MOJO_RESULT_INVALID_ARGUMENT; |
266 | 272 |
267 if (*num_bytes == 0) | 273 if (max_num_bytes_to_discard == 0) |
268 return MOJO_RESULT_OK; // Nothing to do. | 274 return MOJO_RESULT_OK; // Nothing to do. |
269 | 275 |
| 276 uint32_t min_num_bytes_to_discard = all_or_none ? max_num_bytes_to_discard : |
| 277 0; |
| 278 |
270 HandleSignalsState old_producer_state = ProducerGetHandleSignalsStateNoLock(); | 279 HandleSignalsState old_producer_state = ProducerGetHandleSignalsStateNoLock(); |
271 MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, all_or_none); | 280 MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, |
| 281 max_num_bytes_to_discard, |
| 282 min_num_bytes_to_discard); |
272 HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock(); | 283 HandleSignalsState new_producer_state = ProducerGetHandleSignalsStateNoLock(); |
273 if (!new_producer_state.equals(old_producer_state)) | 284 if (!new_producer_state.equals(old_producer_state)) |
274 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); | 285 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); |
275 return rv; | 286 return rv; |
276 } | 287 } |
277 | 288 |
278 MojoResult DataPipe::ConsumerQueryData(uint32_t* num_bytes) { | 289 MojoResult DataPipe::ConsumerQueryData(UserPointer<uint32_t> num_bytes) { |
279 base::AutoLock locker(lock_); | 290 base::AutoLock locker(lock_); |
280 DCHECK(has_local_consumer_no_lock()); | 291 DCHECK(has_local_consumer_no_lock()); |
281 | 292 |
282 if (consumer_in_two_phase_read_no_lock()) | 293 if (consumer_in_two_phase_read_no_lock()) |
283 return MOJO_RESULT_BUSY; | 294 return MOJO_RESULT_BUSY; |
284 | 295 |
285 // Note: Don't need to validate |*num_bytes| for query. | 296 // Note: Don't need to validate |*num_bytes| for query. |
286 return ConsumerQueryDataImplNoLock(num_bytes); | 297 return ConsumerQueryDataImplNoLock(num_bytes); |
287 } | 298 } |
288 | 299 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock( | 415 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock( |
405 const HandleSignalsState& new_consumer_state) { | 416 const HandleSignalsState& new_consumer_state) { |
406 lock_.AssertAcquired(); | 417 lock_.AssertAcquired(); |
407 if (!has_local_consumer_no_lock()) | 418 if (!has_local_consumer_no_lock()) |
408 return; | 419 return; |
409 consumer_waiter_list_->AwakeWaitersForStateChange(new_consumer_state); | 420 consumer_waiter_list_->AwakeWaitersForStateChange(new_consumer_state); |
410 } | 421 } |
411 | 422 |
412 } // namespace system | 423 } // namespace system |
413 } // namespace mojo | 424 } // namespace mojo |
OLD | NEW |