Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(638)

Side by Side Diff: mojo/system/data_pipe.cc

Issue 325213004: Mojo: Wrap the satisfied/unsatisfied wait flags state in a single object. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « mojo/system/data_pipe.h ('k') | mojo/system/local_data_pipe.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 if (!consumer_open_no_lock()) 104 if (!consumer_open_no_lock())
105 return MOJO_RESULT_FAILED_PRECONDITION; 105 return MOJO_RESULT_FAILED_PRECONDITION;
106 106
107 // Returning "busy" takes priority over "invalid argument". 107 // Returning "busy" takes priority over "invalid argument".
108 if (*num_bytes % element_num_bytes_ != 0) 108 if (*num_bytes % element_num_bytes_ != 0)
109 return MOJO_RESULT_INVALID_ARGUMENT; 109 return MOJO_RESULT_INVALID_ARGUMENT;
110 110
111 if (*num_bytes == 0) 111 if (*num_bytes == 0)
112 return MOJO_RESULT_OK; // Nothing to do. 112 return MOJO_RESULT_OK; // Nothing to do.
113 113
114 MojoWaitFlags old_consumer_satisfied_flags = ConsumerSatisfiedFlagsNoLock(); 114 WaitFlagsState old_consumer_state = ConsumerGetWaitFlagsStateNoLock();
115 MojoResult rv = ProducerWriteDataImplNoLock(elements, num_bytes, all_or_none); 115 MojoResult rv = ProducerWriteDataImplNoLock(elements, num_bytes, all_or_none);
116 if (ConsumerSatisfiedFlagsNoLock() != old_consumer_satisfied_flags) 116 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock();
117 if (!new_consumer_state.equals(old_consumer_state))
117 AwakeConsumerWaitersForStateChangeNoLock(); 118 AwakeConsumerWaitersForStateChangeNoLock();
118 return rv; 119 return rv;
119 } 120 }
120 121
121 MojoResult DataPipe::ProducerBeginWriteData(void** buffer, 122 MojoResult DataPipe::ProducerBeginWriteData(void** buffer,
122 uint32_t* buffer_num_bytes, 123 uint32_t* buffer_num_bytes,
123 bool all_or_none) { 124 bool all_or_none) {
124 base::AutoLock locker(lock_); 125 base::AutoLock locker(lock_);
125 DCHECK(has_local_producer_no_lock()); 126 DCHECK(has_local_producer_no_lock());
126 127
(...skipping 19 matching lines...) Expand all
146 147
147 MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) { 148 MojoResult DataPipe::ProducerEndWriteData(uint32_t num_bytes_written) {
148 base::AutoLock locker(lock_); 149 base::AutoLock locker(lock_);
149 DCHECK(has_local_producer_no_lock()); 150 DCHECK(has_local_producer_no_lock());
150 151
151 if (!producer_in_two_phase_write_no_lock()) 152 if (!producer_in_two_phase_write_no_lock())
152 return MOJO_RESULT_FAILED_PRECONDITION; 153 return MOJO_RESULT_FAILED_PRECONDITION;
153 // Note: Allow successful completion of the two-phase write even if the 154 // Note: Allow successful completion of the two-phase write even if the
154 // consumer has been closed. 155 // consumer has been closed.
155 156
156 MojoWaitFlags old_consumer_satisfied_flags = ConsumerSatisfiedFlagsNoLock(); 157 WaitFlagsState old_consumer_state = ConsumerGetWaitFlagsStateNoLock();
157 MojoResult rv; 158 MojoResult rv;
158 if (num_bytes_written > producer_two_phase_max_num_bytes_written_ || 159 if (num_bytes_written > producer_two_phase_max_num_bytes_written_ ||
159 num_bytes_written % element_num_bytes_ != 0) { 160 num_bytes_written % element_num_bytes_ != 0) {
160 rv = MOJO_RESULT_INVALID_ARGUMENT; 161 rv = MOJO_RESULT_INVALID_ARGUMENT;
161 producer_two_phase_max_num_bytes_written_ = 0; 162 producer_two_phase_max_num_bytes_written_ = 0;
162 } else { 163 } else {
163 rv = ProducerEndWriteDataImplNoLock(num_bytes_written); 164 rv = ProducerEndWriteDataImplNoLock(num_bytes_written);
164 } 165 }
165 // Two-phase write ended even on failure. 166 // Two-phase write ended even on failure.
166 DCHECK(!producer_in_two_phase_write_no_lock()); 167 DCHECK(!producer_in_two_phase_write_no_lock());
167 // If we're now writable, we *became* writable (since we weren't writable 168 // If we're now writable, we *became* writable (since we weren't writable
168 // during the two-phase write), so awake producer waiters. 169 // during the two-phase write), so awake producer waiters.
169 if ((ProducerSatisfiedFlagsNoLock() & MOJO_WAIT_FLAG_WRITABLE)) 170 if (ProducerGetWaitFlagsStateNoLock().satisfies(MOJO_WAIT_FLAG_WRITABLE))
170 AwakeProducerWaitersForStateChangeNoLock(); 171 AwakeProducerWaitersForStateChangeNoLock();
171 if (ConsumerSatisfiedFlagsNoLock() != old_consumer_satisfied_flags) 172 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock();
173 if (!new_consumer_state.equals(old_consumer_state))
172 AwakeConsumerWaitersForStateChangeNoLock(); 174 AwakeConsumerWaitersForStateChangeNoLock();
173 return rv; 175 return rv;
174 } 176 }
175 177
176 MojoResult DataPipe::ProducerAddWaiter(Waiter* waiter, 178 MojoResult DataPipe::ProducerAddWaiter(Waiter* waiter,
177 MojoWaitFlags flags, 179 MojoWaitFlags flags,
178 MojoResult wake_result) { 180 MojoResult wake_result) {
179 base::AutoLock locker(lock_); 181 base::AutoLock locker(lock_);
180 DCHECK(has_local_producer_no_lock()); 182 DCHECK(has_local_producer_no_lock());
181 183
182 if ((flags & ProducerSatisfiedFlagsNoLock())) 184 WaitFlagsState producer_state = ProducerGetWaitFlagsStateNoLock();
185 if (producer_state.satisfies(flags))
183 return MOJO_RESULT_ALREADY_EXISTS; 186 return MOJO_RESULT_ALREADY_EXISTS;
184 if (!(flags & ProducerSatisfiableFlagsNoLock())) 187 if (!producer_state.can_satisfy(flags))
185 return MOJO_RESULT_FAILED_PRECONDITION; 188 return MOJO_RESULT_FAILED_PRECONDITION;
186 189
187 producer_waiter_list_->AddWaiter(waiter, flags, wake_result); 190 producer_waiter_list_->AddWaiter(waiter, flags, wake_result);
188 return MOJO_RESULT_OK; 191 return MOJO_RESULT_OK;
189 } 192 }
190 193
191 void DataPipe::ProducerRemoveWaiter(Waiter* waiter) { 194 void DataPipe::ProducerRemoveWaiter(Waiter* waiter) {
192 base::AutoLock locker(lock_); 195 base::AutoLock locker(lock_);
193 DCHECK(has_local_producer_no_lock()); 196 DCHECK(has_local_producer_no_lock());
194 producer_waiter_list_->RemoveWaiter(waiter); 197 producer_waiter_list_->RemoveWaiter(waiter);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 230
228 if (consumer_in_two_phase_read_no_lock()) 231 if (consumer_in_two_phase_read_no_lock())
229 return MOJO_RESULT_BUSY; 232 return MOJO_RESULT_BUSY;
230 233
231 if (*num_bytes % element_num_bytes_ != 0) 234 if (*num_bytes % element_num_bytes_ != 0)
232 return MOJO_RESULT_INVALID_ARGUMENT; 235 return MOJO_RESULT_INVALID_ARGUMENT;
233 236
234 if (*num_bytes == 0) 237 if (*num_bytes == 0)
235 return MOJO_RESULT_OK; // Nothing to do. 238 return MOJO_RESULT_OK; // Nothing to do.
236 239
237 MojoWaitFlags old_producer_satisfied_flags = ProducerSatisfiedFlagsNoLock(); 240 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock();
238 MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, all_or_none); 241 MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, all_or_none);
239 if (ProducerSatisfiedFlagsNoLock() != old_producer_satisfied_flags) 242 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
243 if (!new_producer_state.equals(old_producer_state))
240 AwakeProducerWaitersForStateChangeNoLock(); 244 AwakeProducerWaitersForStateChangeNoLock();
241 return rv; 245 return rv;
242 } 246 }
243 247
244 MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes, 248 MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes,
245 bool all_or_none) { 249 bool all_or_none) {
246 base::AutoLock locker(lock_); 250 base::AutoLock locker(lock_);
247 DCHECK(has_local_consumer_no_lock()); 251 DCHECK(has_local_consumer_no_lock());
248 252
249 if (consumer_in_two_phase_read_no_lock()) 253 if (consumer_in_two_phase_read_no_lock())
250 return MOJO_RESULT_BUSY; 254 return MOJO_RESULT_BUSY;
251 255
252 if (*num_bytes % element_num_bytes_ != 0) 256 if (*num_bytes % element_num_bytes_ != 0)
253 return MOJO_RESULT_INVALID_ARGUMENT; 257 return MOJO_RESULT_INVALID_ARGUMENT;
254 258
255 if (*num_bytes == 0) 259 if (*num_bytes == 0)
256 return MOJO_RESULT_OK; // Nothing to do. 260 return MOJO_RESULT_OK; // Nothing to do.
257 261
258 MojoWaitFlags old_producer_satisfied_flags = ProducerSatisfiedFlagsNoLock(); 262 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock();
259 MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, all_or_none); 263 MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, all_or_none);
260 if (ProducerSatisfiedFlagsNoLock() != old_producer_satisfied_flags) 264 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
265 if (!new_producer_state.equals(old_producer_state))
261 AwakeProducerWaitersForStateChangeNoLock(); 266 AwakeProducerWaitersForStateChangeNoLock();
262 return rv; 267 return rv;
263 } 268 }
264 269
265 MojoResult DataPipe::ConsumerQueryData(uint32_t* num_bytes) { 270 MojoResult DataPipe::ConsumerQueryData(uint32_t* num_bytes) {
266 base::AutoLock locker(lock_); 271 base::AutoLock locker(lock_);
267 DCHECK(has_local_consumer_no_lock()); 272 DCHECK(has_local_consumer_no_lock());
268 273
269 if (consumer_in_two_phase_read_no_lock()) 274 if (consumer_in_two_phase_read_no_lock())
270 return MOJO_RESULT_BUSY; 275 return MOJO_RESULT_BUSY;
(...skipping 22 matching lines...) Expand all
293 return MOJO_RESULT_OK; 298 return MOJO_RESULT_OK;
294 } 299 }
295 300
296 MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) { 301 MojoResult DataPipe::ConsumerEndReadData(uint32_t num_bytes_read) {
297 base::AutoLock locker(lock_); 302 base::AutoLock locker(lock_);
298 DCHECK(has_local_consumer_no_lock()); 303 DCHECK(has_local_consumer_no_lock());
299 304
300 if (!consumer_in_two_phase_read_no_lock()) 305 if (!consumer_in_two_phase_read_no_lock())
301 return MOJO_RESULT_FAILED_PRECONDITION; 306 return MOJO_RESULT_FAILED_PRECONDITION;
302 307
303 MojoWaitFlags old_producer_satisfied_flags = ProducerSatisfiedFlagsNoLock(); 308 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock();
304 MojoResult rv; 309 MojoResult rv;
305 if (num_bytes_read > consumer_two_phase_max_num_bytes_read_ || 310 if (num_bytes_read > consumer_two_phase_max_num_bytes_read_ ||
306 num_bytes_read % element_num_bytes_ != 0) { 311 num_bytes_read % element_num_bytes_ != 0) {
307 rv = MOJO_RESULT_INVALID_ARGUMENT; 312 rv = MOJO_RESULT_INVALID_ARGUMENT;
308 consumer_two_phase_max_num_bytes_read_ = 0; 313 consumer_two_phase_max_num_bytes_read_ = 0;
309 } else { 314 } else {
310 rv = ConsumerEndReadDataImplNoLock(num_bytes_read); 315 rv = ConsumerEndReadDataImplNoLock(num_bytes_read);
311 } 316 }
312 // Two-phase read ended even on failure. 317 // Two-phase read ended even on failure.
313 DCHECK(!consumer_in_two_phase_read_no_lock()); 318 DCHECK(!consumer_in_two_phase_read_no_lock());
314 // If we're now readable, we *became* readable (since we weren't readable 319 // If we're now readable, we *became* readable (since we weren't readable
315 // during the two-phase read), so awake consumer waiters. 320 // during the two-phase read), so awake consumer waiters.
316 if ((ConsumerSatisfiedFlagsNoLock() & MOJO_WAIT_FLAG_READABLE)) 321 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock();
322 if (new_consumer_state.satisfies(MOJO_WAIT_FLAG_READABLE))
317 AwakeConsumerWaitersForStateChangeNoLock(); 323 AwakeConsumerWaitersForStateChangeNoLock();
318 if (ProducerSatisfiedFlagsNoLock() != old_producer_satisfied_flags) 324 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
325 if (!new_producer_state.equals(old_producer_state))
319 AwakeProducerWaitersForStateChangeNoLock(); 326 AwakeProducerWaitersForStateChangeNoLock();
320 return rv; 327 return rv;
321 } 328 }
322 329
323 MojoResult DataPipe::ConsumerAddWaiter(Waiter* waiter, 330 MojoResult DataPipe::ConsumerAddWaiter(Waiter* waiter,
324 MojoWaitFlags flags, 331 MojoWaitFlags flags,
325 MojoResult wake_result) { 332 MojoResult wake_result) {
326 base::AutoLock locker(lock_); 333 base::AutoLock locker(lock_);
327 DCHECK(has_local_consumer_no_lock()); 334 DCHECK(has_local_consumer_no_lock());
328 335
329 if ((flags & ConsumerSatisfiedFlagsNoLock())) 336 WaitFlagsState consumer_state = ConsumerGetWaitFlagsStateNoLock();
337 if (consumer_state.satisfies(flags))
330 return MOJO_RESULT_ALREADY_EXISTS; 338 return MOJO_RESULT_ALREADY_EXISTS;
331 if (!(flags & ConsumerSatisfiableFlagsNoLock())) 339 if (!consumer_state.can_satisfy(flags))
332 return MOJO_RESULT_FAILED_PRECONDITION; 340 return MOJO_RESULT_FAILED_PRECONDITION;
333 341
334 consumer_waiter_list_->AddWaiter(waiter, flags, wake_result); 342 consumer_waiter_list_->AddWaiter(waiter, flags, wake_result);
335 return MOJO_RESULT_OK; 343 return MOJO_RESULT_OK;
336 } 344 }
337 345
338 void DataPipe::ConsumerRemoveWaiter(Waiter* waiter) { 346 void DataPipe::ConsumerRemoveWaiter(Waiter* waiter) {
339 base::AutoLock locker(lock_); 347 base::AutoLock locker(lock_);
340 DCHECK(has_local_consumer_no_lock()); 348 DCHECK(has_local_consumer_no_lock());
341 consumer_waiter_list_->RemoveWaiter(waiter); 349 consumer_waiter_list_->RemoveWaiter(waiter);
(...skipping 28 matching lines...) Expand all
370 DCHECK(!consumer_open_); 378 DCHECK(!consumer_open_);
371 DCHECK(!producer_waiter_list_); 379 DCHECK(!producer_waiter_list_);
372 DCHECK(!consumer_waiter_list_); 380 DCHECK(!consumer_waiter_list_);
373 } 381 }
374 382
375 void DataPipe::AwakeProducerWaitersForStateChangeNoLock() { 383 void DataPipe::AwakeProducerWaitersForStateChangeNoLock() {
376 lock_.AssertAcquired(); 384 lock_.AssertAcquired();
377 if (!has_local_producer_no_lock()) 385 if (!has_local_producer_no_lock())
378 return; 386 return;
379 producer_waiter_list_->AwakeWaitersForStateChange( 387 producer_waiter_list_->AwakeWaitersForStateChange(
380 ProducerSatisfiedFlagsNoLock(), ProducerSatisfiableFlagsNoLock()); 388 ProducerGetWaitFlagsStateNoLock());
381 } 389 }
382 390
383 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock() { 391 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock() {
384 lock_.AssertAcquired(); 392 lock_.AssertAcquired();
385 if (!has_local_consumer_no_lock()) 393 if (!has_local_consumer_no_lock())
386 return; 394 return;
387 consumer_waiter_list_->AwakeWaitersForStateChange( 395 consumer_waiter_list_->AwakeWaitersForStateChange(
388 ConsumerSatisfiedFlagsNoLock(), ConsumerSatisfiableFlagsNoLock()); 396 ConsumerGetWaitFlagsStateNoLock());
389 } 397 }
390 398
391 } // namespace system 399 } // namespace system
392 } // namespace mojo 400 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/data_pipe.h ('k') | mojo/system/local_data_pipe.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698