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 |