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

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

Issue 333713003: Mojo: Plumb wait flags state through DataPipe::Awake...WaitersForStateChangeNoLock(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: wrong change 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') | no next file » | 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 base::AutoLock locker(lock_); 83 base::AutoLock locker(lock_);
84 DCHECK(producer_open_); 84 DCHECK(producer_open_);
85 producer_open_ = false; 85 producer_open_ = false;
86 DCHECK(has_local_producer_no_lock()); 86 DCHECK(has_local_producer_no_lock());
87 producer_waiter_list_.reset(); 87 producer_waiter_list_.reset();
88 // Not a bug, except possibly in "user" code. 88 // Not a bug, except possibly in "user" code.
89 DVLOG_IF(2, producer_in_two_phase_write_no_lock()) 89 DVLOG_IF(2, producer_in_two_phase_write_no_lock())
90 << "Producer closed with active two-phase write"; 90 << "Producer closed with active two-phase write";
91 producer_two_phase_max_num_bytes_written_ = 0; 91 producer_two_phase_max_num_bytes_written_ = 0;
92 ProducerCloseImplNoLock(); 92 ProducerCloseImplNoLock();
93 AwakeConsumerWaitersForStateChangeNoLock(); 93 AwakeConsumerWaitersForStateChangeNoLock(ConsumerGetWaitFlagsStateNoLock());
94 } 94 }
95 95
96 MojoResult DataPipe::ProducerWriteData(const void* elements, 96 MojoResult DataPipe::ProducerWriteData(const void* elements,
97 uint32_t* num_bytes, 97 uint32_t* num_bytes,
98 bool all_or_none) { 98 bool all_or_none) {
99 base::AutoLock locker(lock_); 99 base::AutoLock locker(lock_);
100 DCHECK(has_local_producer_no_lock()); 100 DCHECK(has_local_producer_no_lock());
101 101
102 if (producer_in_two_phase_write_no_lock()) 102 if (producer_in_two_phase_write_no_lock())
103 return MOJO_RESULT_BUSY; 103 return MOJO_RESULT_BUSY;
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 WaitFlagsState old_consumer_state = ConsumerGetWaitFlagsStateNoLock(); 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 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock(); 116 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock();
117 if (!new_consumer_state.equals(old_consumer_state)) 117 if (!new_consumer_state.equals(old_consumer_state))
118 AwakeConsumerWaitersForStateChangeNoLock(); 118 AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state);
119 return rv; 119 return rv;
120 } 120 }
121 121
122 MojoResult DataPipe::ProducerBeginWriteData(void** buffer, 122 MojoResult DataPipe::ProducerBeginWriteData(void** buffer,
123 uint32_t* buffer_num_bytes, 123 uint32_t* buffer_num_bytes,
124 bool all_or_none) { 124 bool all_or_none) {
125 base::AutoLock locker(lock_); 125 base::AutoLock locker(lock_);
126 DCHECK(has_local_producer_no_lock()); 126 DCHECK(has_local_producer_no_lock());
127 127
128 if (producer_in_two_phase_write_no_lock()) 128 if (producer_in_two_phase_write_no_lock())
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 num_bytes_written % element_num_bytes_ != 0) { 160 num_bytes_written % element_num_bytes_ != 0) {
161 rv = MOJO_RESULT_INVALID_ARGUMENT; 161 rv = MOJO_RESULT_INVALID_ARGUMENT;
162 producer_two_phase_max_num_bytes_written_ = 0; 162 producer_two_phase_max_num_bytes_written_ = 0;
163 } else { 163 } else {
164 rv = ProducerEndWriteDataImplNoLock(num_bytes_written); 164 rv = ProducerEndWriteDataImplNoLock(num_bytes_written);
165 } 165 }
166 // Two-phase write ended even on failure. 166 // Two-phase write ended even on failure.
167 DCHECK(!producer_in_two_phase_write_no_lock()); 167 DCHECK(!producer_in_two_phase_write_no_lock());
168 // 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
169 // during the two-phase write), so awake producer waiters. 169 // during the two-phase write), so awake producer waiters.
170 if (ProducerGetWaitFlagsStateNoLock().satisfies(MOJO_WAIT_FLAG_WRITABLE)) 170 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
171 AwakeProducerWaitersForStateChangeNoLock(); 171 if (new_producer_state.satisfies(MOJO_WAIT_FLAG_WRITABLE))
172 AwakeProducerWaitersForStateChangeNoLock(new_producer_state);
172 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock(); 173 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock();
173 if (!new_consumer_state.equals(old_consumer_state)) 174 if (!new_consumer_state.equals(old_consumer_state))
174 AwakeConsumerWaitersForStateChangeNoLock(); 175 AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state);
175 return rv; 176 return rv;
176 } 177 }
177 178
178 MojoResult DataPipe::ProducerAddWaiter(Waiter* waiter, 179 MojoResult DataPipe::ProducerAddWaiter(Waiter* waiter,
179 MojoWaitFlags flags, 180 MojoWaitFlags flags,
180 MojoResult wake_result) { 181 MojoResult wake_result) {
181 base::AutoLock locker(lock_); 182 base::AutoLock locker(lock_);
182 DCHECK(has_local_producer_no_lock()); 183 DCHECK(has_local_producer_no_lock());
183 184
184 WaitFlagsState producer_state = ProducerGetWaitFlagsStateNoLock(); 185 WaitFlagsState producer_state = ProducerGetWaitFlagsStateNoLock();
(...skipping 27 matching lines...) Expand all
212 base::AutoLock locker(lock_); 213 base::AutoLock locker(lock_);
213 DCHECK(consumer_open_); 214 DCHECK(consumer_open_);
214 consumer_open_ = false; 215 consumer_open_ = false;
215 DCHECK(has_local_consumer_no_lock()); 216 DCHECK(has_local_consumer_no_lock());
216 consumer_waiter_list_.reset(); 217 consumer_waiter_list_.reset();
217 // Not a bug, except possibly in "user" code. 218 // Not a bug, except possibly in "user" code.
218 DVLOG_IF(2, consumer_in_two_phase_read_no_lock()) 219 DVLOG_IF(2, consumer_in_two_phase_read_no_lock())
219 << "Consumer closed with active two-phase read"; 220 << "Consumer closed with active two-phase read";
220 consumer_two_phase_max_num_bytes_read_ = 0; 221 consumer_two_phase_max_num_bytes_read_ = 0;
221 ConsumerCloseImplNoLock(); 222 ConsumerCloseImplNoLock();
222 AwakeProducerWaitersForStateChangeNoLock(); 223 AwakeProducerWaitersForStateChangeNoLock(ProducerGetWaitFlagsStateNoLock());
223 } 224 }
224 225
225 MojoResult DataPipe::ConsumerReadData(void* elements, 226 MojoResult DataPipe::ConsumerReadData(void* elements,
226 uint32_t* num_bytes, 227 uint32_t* num_bytes,
227 bool all_or_none) { 228 bool all_or_none) {
228 base::AutoLock locker(lock_); 229 base::AutoLock locker(lock_);
229 DCHECK(has_local_consumer_no_lock()); 230 DCHECK(has_local_consumer_no_lock());
230 231
231 if (consumer_in_two_phase_read_no_lock()) 232 if (consumer_in_two_phase_read_no_lock())
232 return MOJO_RESULT_BUSY; 233 return MOJO_RESULT_BUSY;
233 234
234 if (*num_bytes % element_num_bytes_ != 0) 235 if (*num_bytes % element_num_bytes_ != 0)
235 return MOJO_RESULT_INVALID_ARGUMENT; 236 return MOJO_RESULT_INVALID_ARGUMENT;
236 237
237 if (*num_bytes == 0) 238 if (*num_bytes == 0)
238 return MOJO_RESULT_OK; // Nothing to do. 239 return MOJO_RESULT_OK; // Nothing to do.
239 240
240 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock(); 241 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock();
241 MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, all_or_none); 242 MojoResult rv = ConsumerReadDataImplNoLock(elements, num_bytes, all_or_none);
242 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock(); 243 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
243 if (!new_producer_state.equals(old_producer_state)) 244 if (!new_producer_state.equals(old_producer_state))
244 AwakeProducerWaitersForStateChangeNoLock(); 245 AwakeProducerWaitersForStateChangeNoLock(new_producer_state);
245 return rv; 246 return rv;
246 } 247 }
247 248
248 MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes, 249 MojoResult DataPipe::ConsumerDiscardData(uint32_t* num_bytes,
249 bool all_or_none) { 250 bool all_or_none) {
250 base::AutoLock locker(lock_); 251 base::AutoLock locker(lock_);
251 DCHECK(has_local_consumer_no_lock()); 252 DCHECK(has_local_consumer_no_lock());
252 253
253 if (consumer_in_two_phase_read_no_lock()) 254 if (consumer_in_two_phase_read_no_lock())
254 return MOJO_RESULT_BUSY; 255 return MOJO_RESULT_BUSY;
255 256
256 if (*num_bytes % element_num_bytes_ != 0) 257 if (*num_bytes % element_num_bytes_ != 0)
257 return MOJO_RESULT_INVALID_ARGUMENT; 258 return MOJO_RESULT_INVALID_ARGUMENT;
258 259
259 if (*num_bytes == 0) 260 if (*num_bytes == 0)
260 return MOJO_RESULT_OK; // Nothing to do. 261 return MOJO_RESULT_OK; // Nothing to do.
261 262
262 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock(); 263 WaitFlagsState old_producer_state = ProducerGetWaitFlagsStateNoLock();
263 MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, all_or_none); 264 MojoResult rv = ConsumerDiscardDataImplNoLock(num_bytes, all_or_none);
264 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock(); 265 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
265 if (!new_producer_state.equals(old_producer_state)) 266 if (!new_producer_state.equals(old_producer_state))
266 AwakeProducerWaitersForStateChangeNoLock(); 267 AwakeProducerWaitersForStateChangeNoLock(new_producer_state);
267 return rv; 268 return rv;
268 } 269 }
269 270
270 MojoResult DataPipe::ConsumerQueryData(uint32_t* num_bytes) { 271 MojoResult DataPipe::ConsumerQueryData(uint32_t* num_bytes) {
271 base::AutoLock locker(lock_); 272 base::AutoLock locker(lock_);
272 DCHECK(has_local_consumer_no_lock()); 273 DCHECK(has_local_consumer_no_lock());
273 274
274 if (consumer_in_two_phase_read_no_lock()) 275 if (consumer_in_two_phase_read_no_lock())
275 return MOJO_RESULT_BUSY; 276 return MOJO_RESULT_BUSY;
276 277
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 consumer_two_phase_max_num_bytes_read_ = 0; 314 consumer_two_phase_max_num_bytes_read_ = 0;
314 } else { 315 } else {
315 rv = ConsumerEndReadDataImplNoLock(num_bytes_read); 316 rv = ConsumerEndReadDataImplNoLock(num_bytes_read);
316 } 317 }
317 // Two-phase read ended even on failure. 318 // Two-phase read ended even on failure.
318 DCHECK(!consumer_in_two_phase_read_no_lock()); 319 DCHECK(!consumer_in_two_phase_read_no_lock());
319 // If we're now readable, we *became* readable (since we weren't readable 320 // If we're now readable, we *became* readable (since we weren't readable
320 // during the two-phase read), so awake consumer waiters. 321 // during the two-phase read), so awake consumer waiters.
321 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock(); 322 WaitFlagsState new_consumer_state = ConsumerGetWaitFlagsStateNoLock();
322 if (new_consumer_state.satisfies(MOJO_WAIT_FLAG_READABLE)) 323 if (new_consumer_state.satisfies(MOJO_WAIT_FLAG_READABLE))
323 AwakeConsumerWaitersForStateChangeNoLock(); 324 AwakeConsumerWaitersForStateChangeNoLock(new_consumer_state);
324 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock(); 325 WaitFlagsState new_producer_state = ProducerGetWaitFlagsStateNoLock();
325 if (!new_producer_state.equals(old_producer_state)) 326 if (!new_producer_state.equals(old_producer_state))
326 AwakeProducerWaitersForStateChangeNoLock(); 327 AwakeProducerWaitersForStateChangeNoLock(new_producer_state);
327 return rv; 328 return rv;
328 } 329 }
329 330
330 MojoResult DataPipe::ConsumerAddWaiter(Waiter* waiter, 331 MojoResult DataPipe::ConsumerAddWaiter(Waiter* waiter,
331 MojoWaitFlags flags, 332 MojoWaitFlags flags,
332 MojoResult wake_result) { 333 MojoResult wake_result) {
333 base::AutoLock locker(lock_); 334 base::AutoLock locker(lock_);
334 DCHECK(has_local_consumer_no_lock()); 335 DCHECK(has_local_consumer_no_lock());
335 336
336 WaitFlagsState consumer_state = ConsumerGetWaitFlagsStateNoLock(); 337 WaitFlagsState consumer_state = ConsumerGetWaitFlagsStateNoLock();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 DCHECK_EQ(ValidateCreateOptions(&validated_options, &unused), MOJO_RESULT_OK); 374 DCHECK_EQ(ValidateCreateOptions(&validated_options, &unused), MOJO_RESULT_OK);
374 } 375 }
375 376
376 DataPipe::~DataPipe() { 377 DataPipe::~DataPipe() {
377 DCHECK(!producer_open_); 378 DCHECK(!producer_open_);
378 DCHECK(!consumer_open_); 379 DCHECK(!consumer_open_);
379 DCHECK(!producer_waiter_list_); 380 DCHECK(!producer_waiter_list_);
380 DCHECK(!consumer_waiter_list_); 381 DCHECK(!consumer_waiter_list_);
381 } 382 }
382 383
383 void DataPipe::AwakeProducerWaitersForStateChangeNoLock() { 384 void DataPipe::AwakeProducerWaitersForStateChangeNoLock(
385 const WaitFlagsState& new_producer_state) {
384 lock_.AssertAcquired(); 386 lock_.AssertAcquired();
385 if (!has_local_producer_no_lock()) 387 if (!has_local_producer_no_lock())
386 return; 388 return;
387 producer_waiter_list_->AwakeWaitersForStateChange( 389 producer_waiter_list_->AwakeWaitersForStateChange(new_producer_state);
388 ProducerGetWaitFlagsStateNoLock());
389 } 390 }
390 391
391 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock() { 392 void DataPipe::AwakeConsumerWaitersForStateChangeNoLock(
393 const WaitFlagsState& new_consumer_state) {
392 lock_.AssertAcquired(); 394 lock_.AssertAcquired();
393 if (!has_local_consumer_no_lock()) 395 if (!has_local_consumer_no_lock())
394 return; 396 return;
395 consumer_waiter_list_->AwakeWaitersForStateChange( 397 consumer_waiter_list_->AwakeWaitersForStateChange(new_consumer_state);
396 ConsumerGetWaitFlagsStateNoLock());
397 } 398 }
398 399
399 } // namespace system 400 } // namespace system
400 } // namespace mojo 401 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/data_pipe.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698