OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
10 #include "base/synchronization/condition_variable.h" | 10 #include "base/synchronization/condition_variable.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 | 272 |
273 sw.cv()->Wait(); | 273 sw.cv()->Wait(); |
274 } | 274 } |
275 sw.lock()->Release(); | 275 sw.lock()->Release(); |
276 | 276 |
277 // The address of the WaitableEvent which fired is stored in the SyncWaiter. | 277 // The address of the WaitableEvent which fired is stored in the SyncWaiter. |
278 WaitableEvent *const signaled_event = sw.signaling_event(); | 278 WaitableEvent *const signaled_event = sw.signaling_event(); |
279 // This will store the index of the raw_waitables which fired. | 279 // This will store the index of the raw_waitables which fired. |
280 size_t signaled_index = 0; | 280 size_t signaled_index = 0; |
281 | 281 |
282 // Take the locks of each WaitableEvent in turn (except the signaled one) and | 282 // Take the locks of each WaitableEvent in turn and |
283 // remove our SyncWaiter from the wait-list | 283 // remove our SyncWaiter from the wait-list |
284 for (size_t i = 0; i < count; ++i) { | 284 for (size_t i = 0; i < count; ++i) { |
285 if (raw_waitables[i] != signaled_event) { | 285 if (raw_waitables[i] != signaled_event) { |
286 raw_waitables[i]->kernel_->lock_.Acquire(); | 286 raw_waitables[i]->kernel_->lock_.Acquire(); |
287 // There's no possible ABA issue with the address of the SyncWaiter here | 287 // There's no possible ABA issue with the address of the SyncWaiter here |
288 // because it lives on the stack. Thus the tag value is just the pointer | 288 // because it lives on the stack. Thus the tag value is just the pointer |
289 // value again. | 289 // value again. |
290 raw_waitables[i]->kernel_->Dequeue(&sw, &sw); | 290 raw_waitables[i]->kernel_->Dequeue(&sw, &sw); |
291 raw_waitables[i]->kernel_->lock_.Release(); | 291 raw_waitables[i]->kernel_->lock_.Release(); |
292 } else { | 292 } else { |
293 // We acquire and release the lock in order to ensure that the | |
agl
2014/07/25 17:32:46
It doesn't seem reasonable that WaitMany has this
yhirano
2014/07/29 06:48:11
TimedWait has the property because it acquires the
agl
2014/07/29 21:39:49
Ah, you have found a bug in the code! TimedWait ca
yhirano
2014/07/30 11:43:45
Hmm... I can easily find multiple code relying on
| |
294 // corresponding |Signal| is done at this point. | |
295 raw_waitables[i]->kernel_->lock_.Acquire(); | |
296 raw_waitables[i]->kernel_->lock_.Release(); | |
297 | |
293 signaled_index = i; | 298 signaled_index = i; |
294 } | 299 } |
295 } | 300 } |
296 | 301 |
297 return signaled_index; | 302 return signaled_index; |
298 } | 303 } |
299 | 304 |
300 // ----------------------------------------------------------------------------- | 305 // ----------------------------------------------------------------------------- |
301 // If return value == 0: | 306 // If return value == 0: |
302 // The locks of the WaitableEvents have been taken in order and the Waiter has | 307 // The locks of the WaitableEvents have been taken in order and the Waiter has |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 return true; | 403 return true; |
399 } | 404 } |
400 } | 405 } |
401 | 406 |
402 return false; | 407 return false; |
403 } | 408 } |
404 | 409 |
405 // ----------------------------------------------------------------------------- | 410 // ----------------------------------------------------------------------------- |
406 | 411 |
407 } // namespace base | 412 } // namespace base |
OLD | NEW |