| 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. This matches the behaviour of |Wait| and |TimedWait|. |
| 300 raw_waitables[i]->kernel_->lock_.Acquire(); |
| 301 raw_waitables[i]->kernel_->lock_.Release(); |
| 293 signaled_index = i; | 302 signaled_index = i; |
| 294 } | 303 } |
| 295 } | 304 } |
| 296 | 305 |
| 297 return signaled_index; | 306 return signaled_index; |
| 298 } | 307 } |
| 299 | 308 |
| 300 // ----------------------------------------------------------------------------- | 309 // ----------------------------------------------------------------------------- |
| 301 // If return value == 0: | 310 // If return value == 0: |
| 302 // The locks of the WaitableEvents have been taken in order and the Waiter has | 311 // 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; | 407 return true; |
| 399 } | 408 } |
| 400 } | 409 } |
| 401 | 410 |
| 402 return false; | 411 return false; |
| 403 } | 412 } |
| 404 | 413 |
| 405 // ----------------------------------------------------------------------------- | 414 // ----------------------------------------------------------------------------- |
| 406 | 415 |
| 407 } // namespace base | 416 } // namespace base |
| OLD | NEW |