| 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/edk/system/data_pipe.h" | 5 #include "mojo/edk/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> | 
| 11 | 11 | 
| 12 #include "base/logging.h" | 12 #include "base/logging.h" | 
| 13 #include "mojo/edk/system/configuration.h" | 13 #include "mojo/edk/system/constants.h" | 
| 14 #include "mojo/edk/system/memory.h" | 14 #include "mojo/edk/system/memory.h" | 
| 15 #include "mojo/edk/system/options_validation.h" | 15 #include "mojo/edk/system/options_validation.h" | 
| 16 #include "mojo/edk/system/waiter_list.h" | 16 #include "mojo/edk/system/waiter_list.h" | 
| 17 | 17 | 
| 18 namespace mojo { | 18 namespace mojo { | 
| 19 namespace system { | 19 namespace system { | 
| 20 | 20 | 
| 21 // static | 21 // static | 
| 22 MojoCreateDataPipeOptions DataPipe::GetDefaultCreateOptions() { | 22 const MojoCreateDataPipeOptions DataPipe::kDefaultCreateOptions = { | 
| 23   MojoCreateDataPipeOptions result = { | 23     static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)), | 
| 24       static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)), | 24     MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | 
| 25       MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | 25     1u, | 
| 26       1u, | 26     static_cast<uint32_t>(kDefaultDataPipeCapacityBytes)}; | 
| 27       static_cast<uint32_t>( |  | 
| 28           GetConfiguration().default_data_pipe_capacity_bytes)}; |  | 
| 29   return result; |  | 
| 30 } |  | 
| 31 | 27 | 
| 32 // static | 28 // static | 
| 33 MojoResult DataPipe::ValidateCreateOptions( | 29 MojoResult DataPipe::ValidateCreateOptions( | 
| 34     UserPointer<const MojoCreateDataPipeOptions> in_options, | 30     UserPointer<const MojoCreateDataPipeOptions> in_options, | 
| 35     MojoCreateDataPipeOptions* out_options) { | 31     MojoCreateDataPipeOptions* out_options) { | 
| 36   const MojoCreateDataPipeOptionsFlags kKnownFlags = | 32   const MojoCreateDataPipeOptionsFlags kKnownFlags = | 
| 37       MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD; | 33       MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD; | 
| 38 | 34 | 
| 39   *out_options = GetDefaultCreateOptions(); | 35   *out_options = kDefaultCreateOptions; | 
| 40   if (in_options.IsNull()) | 36   if (in_options.IsNull()) | 
| 41     return MOJO_RESULT_OK; | 37     return MOJO_RESULT_OK; | 
| 42 | 38 | 
| 43   UserOptionsReader<MojoCreateDataPipeOptions> reader(in_options); | 39   UserOptionsReader<MojoCreateDataPipeOptions> reader(in_options); | 
| 44   if (!reader.is_valid()) | 40   if (!reader.is_valid()) | 
| 45     return MOJO_RESULT_INVALID_ARGUMENT; | 41     return MOJO_RESULT_INVALID_ARGUMENT; | 
| 46 | 42 | 
| 47   if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, flags, reader)) | 43   if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, flags, reader)) | 
| 48     return MOJO_RESULT_OK; | 44     return MOJO_RESULT_OK; | 
| 49   if ((reader.options().flags & ~kKnownFlags)) | 45   if ((reader.options().flags & ~kKnownFlags)) | 
| 50     return MOJO_RESULT_UNIMPLEMENTED; | 46     return MOJO_RESULT_UNIMPLEMENTED; | 
| 51   out_options->flags = reader.options().flags; | 47   out_options->flags = reader.options().flags; | 
| 52 | 48 | 
| 53   // Checks for fields beyond |flags|: | 49   // Checks for fields beyond |flags|: | 
| 54 | 50 | 
| 55   if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, element_num_bytes, | 51   if (!OPTIONS_STRUCT_HAS_MEMBER( | 
| 56                                  reader)) | 52           MojoCreateDataPipeOptions, element_num_bytes, reader)) | 
| 57     return MOJO_RESULT_OK; | 53     return MOJO_RESULT_OK; | 
| 58   if (reader.options().element_num_bytes == 0) | 54   if (reader.options().element_num_bytes == 0) | 
| 59     return MOJO_RESULT_INVALID_ARGUMENT; | 55     return MOJO_RESULT_INVALID_ARGUMENT; | 
| 60   out_options->element_num_bytes = reader.options().element_num_bytes; | 56   out_options->element_num_bytes = reader.options().element_num_bytes; | 
| 61 | 57 | 
| 62   if (!OPTIONS_STRUCT_HAS_MEMBER(MojoCreateDataPipeOptions, capacity_num_bytes, | 58   if (!OPTIONS_STRUCT_HAS_MEMBER( | 
| 63                                  reader) || | 59           MojoCreateDataPipeOptions, capacity_num_bytes, reader) || | 
| 64       reader.options().capacity_num_bytes == 0) { | 60       reader.options().capacity_num_bytes == 0) { | 
| 65     // Round the default capacity down to a multiple of the element size (but at | 61     // Round the default capacity down to a multiple of the element size (but at | 
| 66     // least one element). | 62     // least one element). | 
| 67     size_t default_data_pipe_capacity_bytes = |  | 
| 68         GetConfiguration().default_data_pipe_capacity_bytes; |  | 
| 69     out_options->capacity_num_bytes = | 63     out_options->capacity_num_bytes = | 
| 70         std::max(static_cast<uint32_t>(default_data_pipe_capacity_bytes - | 64         std::max(static_cast<uint32_t>(kDefaultDataPipeCapacityBytes - | 
| 71                                        (default_data_pipe_capacity_bytes % | 65                                        (kDefaultDataPipeCapacityBytes % | 
| 72                                         out_options->element_num_bytes)), | 66                                         out_options->element_num_bytes)), | 
| 73                  out_options->element_num_bytes); | 67                  out_options->element_num_bytes); | 
| 74     return MOJO_RESULT_OK; | 68     return MOJO_RESULT_OK; | 
| 75   } | 69   } | 
| 76   if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0) | 70   if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0) | 
| 77     return MOJO_RESULT_INVALID_ARGUMENT; | 71     return MOJO_RESULT_INVALID_ARGUMENT; | 
| 78   if (reader.options().capacity_num_bytes > | 72   if (reader.options().capacity_num_bytes > kMaxDataPipeCapacityBytes) | 
| 79       GetConfiguration().max_data_pipe_capacity_bytes) |  | 
| 80     return MOJO_RESULT_RESOURCE_EXHAUSTED; | 73     return MOJO_RESULT_RESOURCE_EXHAUSTED; | 
| 81   out_options->capacity_num_bytes = reader.options().capacity_num_bytes; | 74   out_options->capacity_num_bytes = reader.options().capacity_num_bytes; | 
| 82 | 75 | 
| 83   return MOJO_RESULT_OK; | 76   return MOJO_RESULT_OK; | 
| 84 } | 77 } | 
| 85 | 78 | 
| 86 void DataPipe::ProducerCancelAllWaiters() { | 79 void DataPipe::ProducerCancelAllWaiters() { | 
| 87   base::AutoLock locker(lock_); | 80   base::AutoLock locker(lock_); | 
| 88   DCHECK(has_local_producer_no_lock()); | 81   DCHECK(has_local_producer_no_lock()); | 
| 89   producer_waiter_list_->CancelAllWaiters(); | 82   producer_waiter_list_->CancelAllWaiters(); | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 148   if (!consumer_open_no_lock()) | 141   if (!consumer_open_no_lock()) | 
| 149     return MOJO_RESULT_FAILED_PRECONDITION; | 142     return MOJO_RESULT_FAILED_PRECONDITION; | 
| 150 | 143 | 
| 151   uint32_t min_num_bytes_to_write = 0; | 144   uint32_t min_num_bytes_to_write = 0; | 
| 152   if (all_or_none) { | 145   if (all_or_none) { | 
| 153     min_num_bytes_to_write = buffer_num_bytes.Get(); | 146     min_num_bytes_to_write = buffer_num_bytes.Get(); | 
| 154     if (min_num_bytes_to_write % element_num_bytes_ != 0) | 147     if (min_num_bytes_to_write % element_num_bytes_ != 0) | 
| 155       return MOJO_RESULT_INVALID_ARGUMENT; | 148       return MOJO_RESULT_INVALID_ARGUMENT; | 
| 156   } | 149   } | 
| 157 | 150 | 
| 158   MojoResult rv = ProducerBeginWriteDataImplNoLock(buffer, buffer_num_bytes, | 151   MojoResult rv = ProducerBeginWriteDataImplNoLock( | 
| 159                                                    min_num_bytes_to_write); | 152       buffer, buffer_num_bytes, min_num_bytes_to_write); | 
| 160   if (rv != MOJO_RESULT_OK) | 153   if (rv != MOJO_RESULT_OK) | 
| 161     return rv; | 154     return rv; | 
| 162   // Note: No need to awake producer waiters, even though we're going from | 155   // Note: No need to awake producer waiters, even though we're going from | 
| 163   // writable to non-writable (since you can't wait on non-writability). | 156   // writable to non-writable (since you can't wait on non-writability). | 
| 164   // Similarly, though this may have discarded data (in "may discard" mode), | 157   // Similarly, though this may have discarded data (in "may discard" mode), | 
| 165   // making it non-readable, there's still no need to awake consumer waiters. | 158   // making it non-readable, there's still no need to awake consumer waiters. | 
| 166   DCHECK(producer_in_two_phase_write_no_lock()); | 159   DCHECK(producer_in_two_phase_write_no_lock()); | 
| 167   return MOJO_RESULT_OK; | 160   return MOJO_RESULT_OK; | 
| 168 } | 161 } | 
| 169 | 162 | 
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 345   if (consumer_in_two_phase_read_no_lock()) | 338   if (consumer_in_two_phase_read_no_lock()) | 
| 346     return MOJO_RESULT_BUSY; | 339     return MOJO_RESULT_BUSY; | 
| 347 | 340 | 
| 348   uint32_t min_num_bytes_to_read = 0; | 341   uint32_t min_num_bytes_to_read = 0; | 
| 349   if (all_or_none) { | 342   if (all_or_none) { | 
| 350     min_num_bytes_to_read = buffer_num_bytes.Get(); | 343     min_num_bytes_to_read = buffer_num_bytes.Get(); | 
| 351     if (min_num_bytes_to_read % element_num_bytes_ != 0) | 344     if (min_num_bytes_to_read % element_num_bytes_ != 0) | 
| 352       return MOJO_RESULT_INVALID_ARGUMENT; | 345       return MOJO_RESULT_INVALID_ARGUMENT; | 
| 353   } | 346   } | 
| 354 | 347 | 
| 355   MojoResult rv = ConsumerBeginReadDataImplNoLock(buffer, buffer_num_bytes, | 348   MojoResult rv = ConsumerBeginReadDataImplNoLock( | 
| 356                                                   min_num_bytes_to_read); | 349       buffer, buffer_num_bytes, min_num_bytes_to_read); | 
| 357   if (rv != MOJO_RESULT_OK) | 350   if (rv != MOJO_RESULT_OK) | 
| 358     return rv; | 351     return rv; | 
| 359   DCHECK(consumer_in_two_phase_read_no_lock()); | 352   DCHECK(consumer_in_two_phase_read_no_lock()); | 
| 360   return MOJO_RESULT_OK; | 353   return MOJO_RESULT_OK; | 
| 361 } | 354 } | 
| 362 | 355 | 
| 363 MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) { | 356 MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) { | 
| 364   base::AutoLock locker(lock_); | 357   base::AutoLock locker(lock_); | 
| 365   DCHECK(has_local_consumer_no_lock()); | 358   DCHECK(has_local_consumer_no_lock()); | 
| 366 | 359 | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 472 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock( | 465 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock( | 
| 473     const HandleSignalsState& new_consumer_state) { | 466     const HandleSignalsState& new_consumer_state) { | 
| 474   lock_.AssertAcquired(); | 467   lock_.AssertAcquired(); | 
| 475   if (!has_local_consumer_no_lock()) | 468   if (!has_local_consumer_no_lock()) | 
| 476     return; | 469     return; | 
| 477   consumer_waiter_list_->AwakeWaitersForStateChange(new_consumer_state); | 470   consumer_waiter_list_->AwakeWaitersForStateChange(new_consumer_state); | 
| 478 } | 471 } | 
| 479 | 472 | 
| 480 }  // namespace system | 473 }  // namespace system | 
| 481 }  // namespace mojo | 474 }  // namespace mojo | 
| OLD | NEW | 
|---|