| 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/awakable_list.h" |
| 13 #include "mojo/edk/system/configuration.h" | 14 #include "mojo/edk/system/configuration.h" |
| 14 #include "mojo/edk/system/memory.h" | 15 #include "mojo/edk/system/memory.h" |
| 15 #include "mojo/edk/system/options_validation.h" | 16 #include "mojo/edk/system/options_validation.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 MojoCreateDataPipeOptions DataPipe::GetDefaultCreateOptions() { |
| 23 MojoCreateDataPipeOptions result = { | 23 MojoCreateDataPipeOptions result = { |
| 24 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)), | 24 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)), |
| 25 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | 25 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, |
| 26 1u, | 26 1u, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0) | 76 if (reader.options().capacity_num_bytes % out_options->element_num_bytes != 0) |
| 77 return MOJO_RESULT_INVALID_ARGUMENT; | 77 return MOJO_RESULT_INVALID_ARGUMENT; |
| 78 if (reader.options().capacity_num_bytes > | 78 if (reader.options().capacity_num_bytes > |
| 79 GetConfiguration().max_data_pipe_capacity_bytes) | 79 GetConfiguration().max_data_pipe_capacity_bytes) |
| 80 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 80 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 81 out_options->capacity_num_bytes = reader.options().capacity_num_bytes; | 81 out_options->capacity_num_bytes = reader.options().capacity_num_bytes; |
| 82 | 82 |
| 83 return MOJO_RESULT_OK; | 83 return MOJO_RESULT_OK; |
| 84 } | 84 } |
| 85 | 85 |
| 86 void DataPipe::ProducerCancelAllWaiters() { | 86 void DataPipe::ProducerCancelAllAwakables() { |
| 87 base::AutoLock locker(lock_); | 87 base::AutoLock locker(lock_); |
| 88 DCHECK(has_local_producer_no_lock()); | 88 DCHECK(has_local_producer_no_lock()); |
| 89 producer_waiter_list_->CancelAllWaiters(); | 89 producer_awakable_list_->CancelAll(); |
| 90 } | 90 } |
| 91 | 91 |
| 92 void DataPipe::ProducerClose() { | 92 void DataPipe::ProducerClose() { |
| 93 base::AutoLock locker(lock_); | 93 base::AutoLock locker(lock_); |
| 94 DCHECK(producer_open_); | 94 DCHECK(producer_open_); |
| 95 producer_open_ = false; | 95 producer_open_ = false; |
| 96 DCHECK(has_local_producer_no_lock()); | 96 DCHECK(has_local_producer_no_lock()); |
| 97 producer_waiter_list_.reset(); | 97 producer_awakable_list_.reset(); |
| 98 // Not a bug, except possibly in "user" code. | 98 // Not a bug, except possibly in "user" code. |
| 99 DVLOG_IF(2, producer_in_two_phase_write_no_lock()) | 99 DVLOG_IF(2, producer_in_two_phase_write_no_lock()) |
| 100 << "Producer closed with active two-phase write"; | 100 << "Producer closed with active two-phase write"; |
| 101 producer_two_phase_max_num_bytes_written_ = 0; | 101 producer_two_phase_max_num_bytes_written_ = 0; |
| 102 ProducerCloseImplNoLock(); | 102 ProducerCloseImplNoLock(); |
| 103 AwakeConsumerWaitersForStateChangeNoLock( | 103 AwakeConsumerAwakablesForStateChangeNoLock( |
| 104 ConsumerGetHandleSignalsStateImplNoLock()); | 104 ConsumerGetHandleSignalsStateImplNoLock()); |
| 105 } | 105 } |
| 106 | 106 |
| 107 MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements, | 107 MojoResult DataPipe::ProducerWriteData(UserPointer<const void> elements, |
| 108 UserPointer<uint32_t> num_bytes, | 108 UserPointer<uint32_t> num_bytes, |
| 109 bool all_or_none) { | 109 bool all_or_none) { |
| 110 base::AutoLock locker(lock_); | 110 base::AutoLock locker(lock_); |
| 111 DCHECK(has_local_producer_no_lock()); | 111 DCHECK(has_local_producer_no_lock()); |
| 112 | 112 |
| 113 if (producer_in_two_phase_write_no_lock()) | 113 if (producer_in_two_phase_write_no_lock()) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 125 | 125 |
| 126 uint32_t min_num_bytes_to_write = all_or_none ? max_num_bytes_to_write : 0; | 126 uint32_t min_num_bytes_to_write = all_or_none ? max_num_bytes_to_write : 0; |
| 127 | 127 |
| 128 HandleSignalsState old_consumer_state = | 128 HandleSignalsState old_consumer_state = |
| 129 ConsumerGetHandleSignalsStateImplNoLock(); | 129 ConsumerGetHandleSignalsStateImplNoLock(); |
| 130 MojoResult rv = ProducerWriteDataImplNoLock( | 130 MojoResult rv = ProducerWriteDataImplNoLock( |
| 131 elements, num_bytes, max_num_bytes_to_write, min_num_bytes_to_write); | 131 elements, num_bytes, max_num_bytes_to_write, min_num_bytes_to_write); |
| 132 HandleSignalsState new_consumer_state = | 132 HandleSignalsState new_consumer_state = |
| 133 ConsumerGetHandleSignalsStateImplNoLock(); | 133 ConsumerGetHandleSignalsStateImplNoLock(); |
| 134 if (!new_consumer_state.equals(old_consumer_state)) | 134 if (!new_consumer_state.equals(old_consumer_state)) |
| 135 AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state); | 135 AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state); |
| 136 return rv; | 136 return rv; |
| 137 } | 137 } |
| 138 | 138 |
| 139 MojoResult DataPipe::ProducerBeginWriteData( | 139 MojoResult DataPipe::ProducerBeginWriteData( |
| 140 UserPointer<void*> buffer, | 140 UserPointer<void*> buffer, |
| 141 UserPointer<uint32_t> buffer_num_bytes, | 141 UserPointer<uint32_t> buffer_num_bytes, |
| 142 bool all_or_none) { | 142 bool all_or_none) { |
| 143 base::AutoLock locker(lock_); | 143 base::AutoLock locker(lock_); |
| 144 DCHECK(has_local_producer_no_lock()); | 144 DCHECK(has_local_producer_no_lock()); |
| 145 | 145 |
| 146 if (producer_in_two_phase_write_no_lock()) | 146 if (producer_in_two_phase_write_no_lock()) |
| 147 return MOJO_RESULT_BUSY; | 147 return MOJO_RESULT_BUSY; |
| 148 if (!consumer_open_no_lock()) | 148 if (!consumer_open_no_lock()) |
| 149 return MOJO_RESULT_FAILED_PRECONDITION; | 149 return MOJO_RESULT_FAILED_PRECONDITION; |
| 150 | 150 |
| 151 uint32_t min_num_bytes_to_write = 0; | 151 uint32_t min_num_bytes_to_write = 0; |
| 152 if (all_or_none) { | 152 if (all_or_none) { |
| 153 min_num_bytes_to_write = buffer_num_bytes.Get(); | 153 min_num_bytes_to_write = buffer_num_bytes.Get(); |
| 154 if (min_num_bytes_to_write % element_num_bytes_ != 0) | 154 if (min_num_bytes_to_write % element_num_bytes_ != 0) |
| 155 return MOJO_RESULT_INVALID_ARGUMENT; | 155 return MOJO_RESULT_INVALID_ARGUMENT; |
| 156 } | 156 } |
| 157 | 157 |
| 158 MojoResult rv = ProducerBeginWriteDataImplNoLock(buffer, buffer_num_bytes, | 158 MojoResult rv = ProducerBeginWriteDataImplNoLock(buffer, buffer_num_bytes, |
| 159 min_num_bytes_to_write); | 159 min_num_bytes_to_write); |
| 160 if (rv != MOJO_RESULT_OK) | 160 if (rv != MOJO_RESULT_OK) |
| 161 return rv; | 161 return rv; |
| 162 // Note: No need to awake producer waiters, even though we're going from | 162 // Note: No need to awake producer awakables, even though we're going from |
| 163 // writable to non-writable (since you can't wait on non-writability). | 163 // writable to non-writable (since you can't wait on non-writability). |
| 164 // Similarly, though this may have discarded data (in "may discard" mode), | 164 // 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. | 165 // making it non-readable, there's still no need to awake consumer awakables. |
| 166 DCHECK(producer_in_two_phase_write_no_lock()); | 166 DCHECK(producer_in_two_phase_write_no_lock()); |
| 167 return MOJO_RESULT_OK; | 167 return MOJO_RESULT_OK; |
| 168 } | 168 } |
| 169 | 169 |
| 170 MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) { | 170 MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) { |
| 171 base::AutoLock locker(lock_); | 171 base::AutoLock locker(lock_); |
| 172 DCHECK(has_local_producer_no_lock()); | 172 DCHECK(has_local_producer_no_lock()); |
| 173 | 173 |
| 174 if (!producer_in_two_phase_write_no_lock()) | 174 if (!producer_in_two_phase_write_no_lock()) |
| 175 return MOJO_RESULT_FAILED_PRECONDITION; | 175 return MOJO_RESULT_FAILED_PRECONDITION; |
| 176 // Note: Allow successful completion of the two-phase write even if the | 176 // Note: Allow successful completion of the two-phase write even if the |
| 177 // consumer has been closed. | 177 // consumer has been closed. |
| 178 | 178 |
| 179 HandleSignalsState old_consumer_state = | 179 HandleSignalsState old_consumer_state = |
| 180 ConsumerGetHandleSignalsStateImplNoLock(); | 180 ConsumerGetHandleSignalsStateImplNoLock(); |
| 181 MojoResult rv; | 181 MojoResult rv; |
| 182 if (num_bytes_written > producer_two_phase_max_num_bytes_written_ || | 182 if (num_bytes_written > producer_two_phase_max_num_bytes_written_ || |
| 183 num_bytes_written % element_num_bytes_ != 0) { | 183 num_bytes_written % element_num_bytes_ != 0) { |
| 184 rv = MOJO_RESULT_INVALID_ARGUMENT; | 184 rv = MOJO_RESULT_INVALID_ARGUMENT; |
| 185 producer_two_phase_max_num_bytes_written_ = 0; | 185 producer_two_phase_max_num_bytes_written_ = 0; |
| 186 } else { | 186 } else { |
| 187 rv = ProducerEndWriteDataImplNoLock(num_bytes_written); | 187 rv = ProducerEndWriteDataImplNoLock(num_bytes_written); |
| 188 } | 188 } |
| 189 // Two-phase write ended even on failure. | 189 // Two-phase write ended even on failure. |
| 190 DCHECK(!producer_in_two_phase_write_no_lock()); | 190 DCHECK(!producer_in_two_phase_write_no_lock()); |
| 191 // If we're now writable, we *became* writable (since we weren't writable | 191 // If we're now writable, we *became* writable (since we weren't writable |
| 192 // during the two-phase write), so awake producer waiters. | 192 // during the two-phase write), so awake producer awakables. |
| 193 HandleSignalsState new_producer_state = | 193 HandleSignalsState new_producer_state = |
| 194 ProducerGetHandleSignalsStateImplNoLock(); | 194 ProducerGetHandleSignalsStateImplNoLock(); |
| 195 if (new_producer_state.satisfies(MOJO_HANDLE_SIGNAL_WRITABLE)) | 195 if (new_producer_state.satisfies(MOJO_HANDLE_SIGNAL_WRITABLE)) |
| 196 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); | 196 AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
| 197 HandleSignalsState new_consumer_state = | 197 HandleSignalsState new_consumer_state = |
| 198 ConsumerGetHandleSignalsStateImplNoLock(); | 198 ConsumerGetHandleSignalsStateImplNoLock(); |
| 199 if (!new_consumer_state.equals(old_consumer_state)) | 199 if (!new_consumer_state.equals(old_consumer_state)) |
| 200 AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state); | 200 AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state); |
| 201 return rv; | 201 return rv; |
| 202 } | 202 } |
| 203 | 203 |
| 204 HandleSignalsState DataPipe::ProducerGetHandleSignalsState() { | 204 HandleSignalsState DataPipe::ProducerGetHandleSignalsState() { |
| 205 base::AutoLock locker(lock_); | 205 base::AutoLock locker(lock_); |
| 206 DCHECK(has_local_producer_no_lock()); | 206 DCHECK(has_local_producer_no_lock()); |
| 207 return ProducerGetHandleSignalsStateImplNoLock(); | 207 return ProducerGetHandleSignalsStateImplNoLock(); |
| 208 } | 208 } |
| 209 | 209 |
| 210 MojoResult DataPipe::ProducerAddWaiter(Waiter* waiter, | 210 MojoResult DataPipe::ProducerAddAwakable(Awakable* awakable, |
| 211 MojoHandleSignals signals, | 211 MojoHandleSignals signals, |
| 212 uint32_t context, | 212 uint32_t context, |
| 213 HandleSignalsState* signals_state) { | 213 HandleSignalsState* signals_state) { |
| 214 base::AutoLock locker(lock_); | 214 base::AutoLock locker(lock_); |
| 215 DCHECK(has_local_producer_no_lock()); | 215 DCHECK(has_local_producer_no_lock()); |
| 216 | 216 |
| 217 HandleSignalsState producer_state = ProducerGetHandleSignalsStateImplNoLock(); | 217 HandleSignalsState producer_state = ProducerGetHandleSignalsStateImplNoLock(); |
| 218 if (producer_state.satisfies(signals)) { | 218 if (producer_state.satisfies(signals)) { |
| 219 if (signals_state) | 219 if (signals_state) |
| 220 *signals_state = producer_state; | 220 *signals_state = producer_state; |
| 221 return MOJO_RESULT_ALREADY_EXISTS; | 221 return MOJO_RESULT_ALREADY_EXISTS; |
| 222 } | 222 } |
| 223 if (!producer_state.can_satisfy(signals)) { | 223 if (!producer_state.can_satisfy(signals)) { |
| 224 if (signals_state) | 224 if (signals_state) |
| 225 *signals_state = producer_state; | 225 *signals_state = producer_state; |
| 226 return MOJO_RESULT_FAILED_PRECONDITION; | 226 return MOJO_RESULT_FAILED_PRECONDITION; |
| 227 } | 227 } |
| 228 | 228 |
| 229 producer_waiter_list_->AddWaiter(waiter, signals, context); | 229 producer_awakable_list_->Add(awakable, signals, context); |
| 230 return MOJO_RESULT_OK; | 230 return MOJO_RESULT_OK; |
| 231 } | 231 } |
| 232 | 232 |
| 233 void DataPipe::ProducerRemoveWaiter(Waiter* waiter, | 233 void DataPipe::ProducerRemoveAwakable(Awakable* awakable, |
| 234 HandleSignalsState* signals_state) { | 234 HandleSignalsState* signals_state) { |
| 235 base::AutoLock locker(lock_); | 235 base::AutoLock locker(lock_); |
| 236 DCHECK(has_local_producer_no_lock()); | 236 DCHECK(has_local_producer_no_lock()); |
| 237 producer_waiter_list_->RemoveWaiter(waiter); | 237 producer_awakable_list_->Remove(awakable); |
| 238 if (signals_state) | 238 if (signals_state) |
| 239 *signals_state = ProducerGetHandleSignalsStateImplNoLock(); | 239 *signals_state = ProducerGetHandleSignalsStateImplNoLock(); |
| 240 } | 240 } |
| 241 | 241 |
| 242 bool DataPipe::ProducerIsBusy() const { | 242 bool DataPipe::ProducerIsBusy() const { |
| 243 base::AutoLock locker(lock_); | 243 base::AutoLock locker(lock_); |
| 244 return producer_in_two_phase_write_no_lock(); | 244 return producer_in_two_phase_write_no_lock(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 void DataPipe::ConsumerCancelAllWaiters() { | 247 void DataPipe::ConsumerCancelAllAwakables() { |
| 248 base::AutoLock locker(lock_); | 248 base::AutoLock locker(lock_); |
| 249 DCHECK(has_local_consumer_no_lock()); | 249 DCHECK(has_local_consumer_no_lock()); |
| 250 consumer_waiter_list_->CancelAllWaiters(); | 250 consumer_awakable_list_->CancelAll(); |
| 251 } | 251 } |
| 252 | 252 |
| 253 void DataPipe::ConsumerClose() { | 253 void DataPipe::ConsumerClose() { |
| 254 base::AutoLock locker(lock_); | 254 base::AutoLock locker(lock_); |
| 255 DCHECK(consumer_open_); | 255 DCHECK(consumer_open_); |
| 256 consumer_open_ = false; | 256 consumer_open_ = false; |
| 257 DCHECK(has_local_consumer_no_lock()); | 257 DCHECK(has_local_consumer_no_lock()); |
| 258 consumer_waiter_list_.reset(); | 258 consumer_awakable_list_.reset(); |
| 259 // Not a bug, except possibly in "user" code. | 259 // Not a bug, except possibly in "user" code. |
| 260 DVLOG_IF(2, consumer_in_two_phase_read_no_lock()) | 260 DVLOG_IF(2, consumer_in_two_phase_read_no_lock()) |
| 261 << "Consumer closed with active two-phase read"; | 261 << "Consumer closed with active two-phase read"; |
| 262 consumer_two_phase_max_num_bytes_read_ = 0; | 262 consumer_two_phase_max_num_bytes_read_ = 0; |
| 263 ConsumerCloseImplNoLock(); | 263 ConsumerCloseImplNoLock(); |
| 264 AwakeProducerWaitersForStateChangeNoLock( | 264 AwakeProducerAwakablesForStateChangeNoLock( |
| 265 ProducerGetHandleSignalsStateImplNoLock()); | 265 ProducerGetHandleSignalsStateImplNoLock()); |
| 266 } | 266 } |
| 267 | 267 |
| 268 MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements, | 268 MojoResult DataPipe::ConsumerReadData(UserPointer<void> elements, |
| 269 UserPointer<uint32_t> num_bytes, | 269 UserPointer<uint32_t> num_bytes, |
| 270 bool all_or_none, | 270 bool all_or_none, |
| 271 bool peek) { | 271 bool peek) { |
| 272 base::AutoLock locker(lock_); | 272 base::AutoLock locker(lock_); |
| 273 DCHECK(has_local_consumer_no_lock()); | 273 DCHECK(has_local_consumer_no_lock()); |
| 274 | 274 |
| 275 if (consumer_in_two_phase_read_no_lock()) | 275 if (consumer_in_two_phase_read_no_lock()) |
| 276 return MOJO_RESULT_BUSY; | 276 return MOJO_RESULT_BUSY; |
| 277 | 277 |
| 278 uint32_t max_num_bytes_to_read = num_bytes.Get(); | 278 uint32_t max_num_bytes_to_read = num_bytes.Get(); |
| 279 if (max_num_bytes_to_read % element_num_bytes_ != 0) | 279 if (max_num_bytes_to_read % element_num_bytes_ != 0) |
| 280 return MOJO_RESULT_INVALID_ARGUMENT; | 280 return MOJO_RESULT_INVALID_ARGUMENT; |
| 281 | 281 |
| 282 if (max_num_bytes_to_read == 0) | 282 if (max_num_bytes_to_read == 0) |
| 283 return MOJO_RESULT_OK; // Nothing to do. | 283 return MOJO_RESULT_OK; // Nothing to do. |
| 284 | 284 |
| 285 uint32_t min_num_bytes_to_read = all_or_none ? max_num_bytes_to_read : 0; | 285 uint32_t min_num_bytes_to_read = all_or_none ? max_num_bytes_to_read : 0; |
| 286 | 286 |
| 287 HandleSignalsState old_producer_state = | 287 HandleSignalsState old_producer_state = |
| 288 ProducerGetHandleSignalsStateImplNoLock(); | 288 ProducerGetHandleSignalsStateImplNoLock(); |
| 289 MojoResult rv = ConsumerReadDataImplNoLock( | 289 MojoResult rv = ConsumerReadDataImplNoLock( |
| 290 elements, num_bytes, max_num_bytes_to_read, min_num_bytes_to_read, peek); | 290 elements, num_bytes, max_num_bytes_to_read, min_num_bytes_to_read, peek); |
| 291 HandleSignalsState new_producer_state = | 291 HandleSignalsState new_producer_state = |
| 292 ProducerGetHandleSignalsStateImplNoLock(); | 292 ProducerGetHandleSignalsStateImplNoLock(); |
| 293 if (!new_producer_state.equals(old_producer_state)) | 293 if (!new_producer_state.equals(old_producer_state)) |
| 294 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); | 294 AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
| 295 return rv; | 295 return rv; |
| 296 } | 296 } |
| 297 | 297 |
| 298 MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes, | 298 MojoResult DataPipe::ConsumerDiscardData(UserPointer<uint32_t> num_bytes, |
| 299 bool all_or_none) { | 299 bool all_or_none) { |
| 300 base::AutoLock locker(lock_); | 300 base::AutoLock locker(lock_); |
| 301 DCHECK(has_local_consumer_no_lock()); | 301 DCHECK(has_local_consumer_no_lock()); |
| 302 | 302 |
| 303 if (consumer_in_two_phase_read_no_lock()) | 303 if (consumer_in_two_phase_read_no_lock()) |
| 304 return MOJO_RESULT_BUSY; | 304 return MOJO_RESULT_BUSY; |
| 305 | 305 |
| 306 uint32_t max_num_bytes_to_discard = num_bytes.Get(); | 306 uint32_t max_num_bytes_to_discard = num_bytes.Get(); |
| 307 if (max_num_bytes_to_discard % element_num_bytes_ != 0) | 307 if (max_num_bytes_to_discard % element_num_bytes_ != 0) |
| 308 return MOJO_RESULT_INVALID_ARGUMENT; | 308 return MOJO_RESULT_INVALID_ARGUMENT; |
| 309 | 309 |
| 310 if (max_num_bytes_to_discard == 0) | 310 if (max_num_bytes_to_discard == 0) |
| 311 return MOJO_RESULT_OK; // Nothing to do. | 311 return MOJO_RESULT_OK; // Nothing to do. |
| 312 | 312 |
| 313 uint32_t min_num_bytes_to_discard = | 313 uint32_t min_num_bytes_to_discard = |
| 314 all_or_none ? max_num_bytes_to_discard : 0; | 314 all_or_none ? max_num_bytes_to_discard : 0; |
| 315 | 315 |
| 316 HandleSignalsState old_producer_state = | 316 HandleSignalsState old_producer_state = |
| 317 ProducerGetHandleSignalsStateImplNoLock(); | 317 ProducerGetHandleSignalsStateImplNoLock(); |
| 318 MojoResult rv = ConsumerDiscardDataImplNoLock( | 318 MojoResult rv = ConsumerDiscardDataImplNoLock( |
| 319 num_bytes, max_num_bytes_to_discard, min_num_bytes_to_discard); | 319 num_bytes, max_num_bytes_to_discard, min_num_bytes_to_discard); |
| 320 HandleSignalsState new_producer_state = | 320 HandleSignalsState new_producer_state = |
| 321 ProducerGetHandleSignalsStateImplNoLock(); | 321 ProducerGetHandleSignalsStateImplNoLock(); |
| 322 if (!new_producer_state.equals(old_producer_state)) | 322 if (!new_producer_state.equals(old_producer_state)) |
| 323 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); | 323 AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
| 324 return rv; | 324 return rv; |
| 325 } | 325 } |
| 326 | 326 |
| 327 MojoResult DataPipe::ConsumerQueryData(UserPointer<uint32_t> num_bytes) { | 327 MojoResult DataPipe::ConsumerQueryData(UserPointer<uint32_t> num_bytes) { |
| 328 base::AutoLock locker(lock_); | 328 base::AutoLock locker(lock_); |
| 329 DCHECK(has_local_consumer_no_lock()); | 329 DCHECK(has_local_consumer_no_lock()); |
| 330 | 330 |
| 331 if (consumer_in_two_phase_read_no_lock()) | 331 if (consumer_in_two_phase_read_no_lock()) |
| 332 return MOJO_RESULT_BUSY; | 332 return MOJO_RESULT_BUSY; |
| 333 | 333 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 if (num_bytes_read > consumer_two_phase_max_num_bytes_read_ || | 373 if (num_bytes_read > consumer_two_phase_max_num_bytes_read_ || |
| 374 num_bytes_read % element_num_bytes_ != 0) { | 374 num_bytes_read % element_num_bytes_ != 0) { |
| 375 rv = MOJO_RESULT_INVALID_ARGUMENT; | 375 rv = MOJO_RESULT_INVALID_ARGUMENT; |
| 376 consumer_two_phase_max_num_bytes_read_ = 0; | 376 consumer_two_phase_max_num_bytes_read_ = 0; |
| 377 } else { | 377 } else { |
| 378 rv = ConsumerEndReadDataImplNoLock(num_bytes_read); | 378 rv = ConsumerEndReadDataImplNoLock(num_bytes_read); |
| 379 } | 379 } |
| 380 // Two-phase read ended even on failure. | 380 // Two-phase read ended even on failure. |
| 381 DCHECK(!consumer_in_two_phase_read_no_lock()); | 381 DCHECK(!consumer_in_two_phase_read_no_lock()); |
| 382 // If we're now readable, we *became* readable (since we weren't readable | 382 // If we're now readable, we *became* readable (since we weren't readable |
| 383 // during the two-phase read), so awake consumer waiters. | 383 // during the two-phase read), so awake consumer awakables. |
| 384 HandleSignalsState new_consumer_state = | 384 HandleSignalsState new_consumer_state = |
| 385 ConsumerGetHandleSignalsStateImplNoLock(); | 385 ConsumerGetHandleSignalsStateImplNoLock(); |
| 386 if (new_consumer_state.satisfies(MOJO_HANDLE_SIGNAL_READABLE)) | 386 if (new_consumer_state.satisfies(MOJO_HANDLE_SIGNAL_READABLE)) |
| 387 AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state); | 387 AwakeConsumerAwakablesForStateChangeNoLock(new_consumer_state); |
| 388 HandleSignalsState new_producer_state = | 388 HandleSignalsState new_producer_state = |
| 389 ProducerGetHandleSignalsStateImplNoLock(); | 389 ProducerGetHandleSignalsStateImplNoLock(); |
| 390 if (!new_producer_state.equals(old_producer_state)) | 390 if (!new_producer_state.equals(old_producer_state)) |
| 391 AwakeProducerWaitersForStateChangeNoLock(new_producer_state); | 391 AwakeProducerAwakablesForStateChangeNoLock(new_producer_state); |
| 392 return rv; | 392 return rv; |
| 393 } | 393 } |
| 394 | 394 |
| 395 HandleSignalsState DataPipe::ConsumerGetHandleSignalsState() { | 395 HandleSignalsState DataPipe::ConsumerGetHandleSignalsState() { |
| 396 base::AutoLock locker(lock_); | 396 base::AutoLock locker(lock_); |
| 397 DCHECK(has_local_consumer_no_lock()); | 397 DCHECK(has_local_consumer_no_lock()); |
| 398 return ConsumerGetHandleSignalsStateImplNoLock(); | 398 return ConsumerGetHandleSignalsStateImplNoLock(); |
| 399 } | 399 } |
| 400 | 400 |
| 401 MojoResult DataPipe::ConsumerAddWaiter(Waiter* waiter, | 401 MojoResult DataPipe::ConsumerAddAwakable(Awakable* awakable, |
| 402 MojoHandleSignals signals, | 402 MojoHandleSignals signals, |
| 403 uint32_t context, | 403 uint32_t context, |
| 404 HandleSignalsState* signals_state) { | 404 HandleSignalsState* signals_state) { |
| 405 base::AutoLock locker(lock_); | 405 base::AutoLock locker(lock_); |
| 406 DCHECK(has_local_consumer_no_lock()); | 406 DCHECK(has_local_consumer_no_lock()); |
| 407 | 407 |
| 408 HandleSignalsState consumer_state = ConsumerGetHandleSignalsStateImplNoLock(); | 408 HandleSignalsState consumer_state = ConsumerGetHandleSignalsStateImplNoLock(); |
| 409 if (consumer_state.satisfies(signals)) { | 409 if (consumer_state.satisfies(signals)) { |
| 410 if (signals_state) | 410 if (signals_state) |
| 411 *signals_state = consumer_state; | 411 *signals_state = consumer_state; |
| 412 return MOJO_RESULT_ALREADY_EXISTS; | 412 return MOJO_RESULT_ALREADY_EXISTS; |
| 413 } | 413 } |
| 414 if (!consumer_state.can_satisfy(signals)) { | 414 if (!consumer_state.can_satisfy(signals)) { |
| 415 if (signals_state) | 415 if (signals_state) |
| 416 *signals_state = consumer_state; | 416 *signals_state = consumer_state; |
| 417 return MOJO_RESULT_FAILED_PRECONDITION; | 417 return MOJO_RESULT_FAILED_PRECONDITION; |
| 418 } | 418 } |
| 419 | 419 |
| 420 consumer_waiter_list_->AddWaiter(waiter, signals, context); | 420 consumer_awakable_list_->Add(awakable, signals, context); |
| 421 return MOJO_RESULT_OK; | 421 return MOJO_RESULT_OK; |
| 422 } | 422 } |
| 423 | 423 |
| 424 void DataPipe::ConsumerRemoveWaiter(Waiter* waiter, | 424 void DataPipe::ConsumerRemoveAwakable(Awakable* awakable, |
| 425 HandleSignalsState* signals_state) { | 425 HandleSignalsState* signals_state) { |
| 426 base::AutoLock locker(lock_); | 426 base::AutoLock locker(lock_); |
| 427 DCHECK(has_local_consumer_no_lock()); | 427 DCHECK(has_local_consumer_no_lock()); |
| 428 consumer_waiter_list_->RemoveWaiter(waiter); | 428 consumer_awakable_list_->Remove(awakable); |
| 429 if (signals_state) | 429 if (signals_state) |
| 430 *signals_state = ConsumerGetHandleSignalsStateImplNoLock(); | 430 *signals_state = ConsumerGetHandleSignalsStateImplNoLock(); |
| 431 } | 431 } |
| 432 | 432 |
| 433 bool DataPipe::ConsumerIsBusy() const { | 433 bool DataPipe::ConsumerIsBusy() const { |
| 434 base::AutoLock locker(lock_); | 434 base::AutoLock locker(lock_); |
| 435 return consumer_in_two_phase_read_no_lock(); | 435 return consumer_in_two_phase_read_no_lock(); |
| 436 } | 436 } |
| 437 | 437 |
| 438 DataPipe::DataPipe(bool has_local_producer, | 438 DataPipe::DataPipe(bool has_local_producer, |
| 439 bool has_local_consumer, | 439 bool has_local_consumer, |
| 440 const MojoCreateDataPipeOptions& validated_options) | 440 const MojoCreateDataPipeOptions& validated_options) |
| 441 : may_discard_((validated_options.flags & | 441 : may_discard_((validated_options.flags & |
| 442 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)), | 442 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)), |
| 443 element_num_bytes_(validated_options.element_num_bytes), | 443 element_num_bytes_(validated_options.element_num_bytes), |
| 444 capacity_num_bytes_(validated_options.capacity_num_bytes), | 444 capacity_num_bytes_(validated_options.capacity_num_bytes), |
| 445 producer_open_(true), | 445 producer_open_(true), |
| 446 consumer_open_(true), | 446 consumer_open_(true), |
| 447 producer_waiter_list_(has_local_producer ? new WaiterList() : nullptr), | 447 producer_awakable_list_(has_local_producer ? new AwakableList() |
| 448 consumer_waiter_list_(has_local_consumer ? new WaiterList() : nullptr), | 448 : nullptr), |
| 449 consumer_awakable_list_(has_local_consumer ? new AwakableList() |
| 450 : nullptr), |
| 449 producer_two_phase_max_num_bytes_written_(0), | 451 producer_two_phase_max_num_bytes_written_(0), |
| 450 consumer_two_phase_max_num_bytes_read_(0) { | 452 consumer_two_phase_max_num_bytes_read_(0) { |
| 451 // Check that the passed in options actually are validated. | 453 // Check that the passed in options actually are validated. |
| 452 MojoCreateDataPipeOptions unused = {0}; | 454 MojoCreateDataPipeOptions unused = {0}; |
| 453 DCHECK_EQ(ValidateCreateOptions(MakeUserPointer(&validated_options), &unused), | 455 DCHECK_EQ(ValidateCreateOptions(MakeUserPointer(&validated_options), &unused), |
| 454 MOJO_RESULT_OK); | 456 MOJO_RESULT_OK); |
| 455 } | 457 } |
| 456 | 458 |
| 457 DataPipe::~DataPipe() { | 459 DataPipe::~DataPipe() { |
| 458 DCHECK(!producer_open_); | 460 DCHECK(!producer_open_); |
| 459 DCHECK(!consumer_open_); | 461 DCHECK(!consumer_open_); |
| 460 DCHECK(!producer_waiter_list_); | 462 DCHECK(!producer_awakable_list_); |
| 461 DCHECK(!consumer_waiter_list_); | 463 DCHECK(!consumer_awakable_list_); |
| 462 } | 464 } |
| 463 | 465 |
| 464 void DataPipe::AwakeProducerWaitersForStateChangeNoLock( | 466 void DataPipe::AwakeProducerAwakablesForStateChangeNoLock( |
| 465 const HandleSignalsState& new_producer_state) { | 467 const HandleSignalsState& new_producer_state) { |
| 466 lock_.AssertAcquired(); | 468 lock_.AssertAcquired(); |
| 467 if (!has_local_producer_no_lock()) | 469 if (!has_local_producer_no_lock()) |
| 468 return; | 470 return; |
| 469 producer_waiter_list_->AwakeWaitersForStateChange(new_producer_state); | 471 producer_awakable_list_->AwakeForStateChange(new_producer_state); |
| 470 } | 472 } |
| 471 | 473 |
| 472 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock( | 474 void DataPipe::AwakeConsumerAwakablesForStateChangeNoLock( |
| 473 const HandleSignalsState& new_consumer_state) { | 475 const HandleSignalsState& new_consumer_state) { |
| 474 lock_.AssertAcquired(); | 476 lock_.AssertAcquired(); |
| 475 if (!has_local_consumer_no_lock()) | 477 if (!has_local_consumer_no_lock()) |
| 476 return; | 478 return; |
| 477 consumer_waiter_list_->AwakeWaitersForStateChange(new_consumer_state); | 479 consumer_awakable_list_->AwakeForStateChange(new_consumer_state); |
| 478 } | 480 } |
| 479 | 481 |
| 480 } // namespace system | 482 } // namespace system |
| 481 } // namespace mojo | 483 } // namespace mojo |
| OLD | NEW |