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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 const bool return_value = sw.fired(); | 190 const bool return_value = sw.fired(); |
191 | 191 |
192 // We can't acquire @lock_ before releasing the SyncWaiter lock (because | 192 // We can't acquire @lock_ before releasing the SyncWaiter lock (because |
193 // of locking order), however, in between the two a signal could be fired | 193 // of locking order), however, in between the two a signal could be fired |
194 // and @sw would accept it, however we will still return false, so the | 194 // and @sw would accept it, however we will still return false, so the |
195 // signal would be lost on an auto-reset WaitableEvent. Thus we call | 195 // signal would be lost on an auto-reset WaitableEvent. Thus we call |
196 // Disable which makes sw::Fire return false. | 196 // Disable which makes sw::Fire return false. |
197 sw.Disable(); | 197 sw.Disable(); |
198 sw.lock()->Release(); | 198 sw.lock()->Release(); |
199 | 199 |
| 200 // This is a bug that has been enshrined in the interface of |
| 201 // WaitableEvent now: |Dequeue| is called even when |sw.fired()| is true, |
| 202 // even though it'll always return false in that case. However, taking |
| 203 // the lock ensures that |Signal| has completed before we return and |
| 204 // means that a WaitableEvent can synchronise its own destruction. |
200 kernel_->lock_.Acquire(); | 205 kernel_->lock_.Acquire(); |
201 kernel_->Dequeue(&sw, &sw); | 206 kernel_->Dequeue(&sw, &sw); |
202 kernel_->lock_.Release(); | 207 kernel_->lock_.Release(); |
203 | 208 |
204 return return_value; | 209 return return_value; |
205 } | 210 } |
206 | 211 |
207 if (finite_time) { | 212 if (finite_time) { |
208 const TimeDelta max_wait(end_time - current_time); | 213 const TimeDelta max_wait(end_time - current_time); |
209 sw.cv()->TimedWait(max_wait); | 214 sw.cv()->TimedWait(max_wait); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 // remove our SyncWaiter from the wait-list | 288 // remove our SyncWaiter from the wait-list |
284 for (size_t i = 0; i < count; ++i) { | 289 for (size_t i = 0; i < count; ++i) { |
285 if (raw_waitables[i] != signaled_event) { | 290 if (raw_waitables[i] != signaled_event) { |
286 raw_waitables[i]->kernel_->lock_.Acquire(); | 291 raw_waitables[i]->kernel_->lock_.Acquire(); |
287 // There's no possible ABA issue with the address of the SyncWaiter here | 292 // 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 | 293 // because it lives on the stack. Thus the tag value is just the pointer |
289 // value again. | 294 // value again. |
290 raw_waitables[i]->kernel_->Dequeue(&sw, &sw); | 295 raw_waitables[i]->kernel_->Dequeue(&sw, &sw); |
291 raw_waitables[i]->kernel_->lock_.Release(); | 296 raw_waitables[i]->kernel_->lock_.Release(); |
292 } else { | 297 } else { |
| 298 // By taking this lock here we ensure that |Signal| has completed by the |
| 299 // time we return, because |Signal| holds this lock. This matches the |
| 300 // behaviour of |Wait| and |TimedWait|. |
| 301 raw_waitables[i]->kernel_->lock_.Acquire(); |
| 302 raw_waitables[i]->kernel_->lock_.Release(); |
293 signaled_index = i; | 303 signaled_index = i; |
294 } | 304 } |
295 } | 305 } |
296 | 306 |
297 return signaled_index; | 307 return signaled_index; |
298 } | 308 } |
299 | 309 |
300 // ----------------------------------------------------------------------------- | 310 // ----------------------------------------------------------------------------- |
301 // If return value == 0: | 311 // If return value == 0: |
302 // The locks of the WaitableEvents have been taken in order and the Waiter has | 312 // 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; | 408 return true; |
399 } | 409 } |
400 } | 410 } |
401 | 411 |
402 return false; | 412 return false; |
403 } | 413 } |
404 | 414 |
405 // ----------------------------------------------------------------------------- | 415 // ----------------------------------------------------------------------------- |
406 | 416 |
407 } // namespace base | 417 } // namespace base |
OLD | NEW |