| 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 |