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 |