| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 base::ConditionVariable cv_; | 152 base::ConditionVariable cv_; |
| 153 }; | 153 }; |
| 154 | 154 |
| 155 void WaitableEvent::Wait() { | 155 void WaitableEvent::Wait() { |
| 156 bool result = TimedWait(TimeDelta::FromSeconds(-1)); | 156 bool result = TimedWait(TimeDelta::FromSeconds(-1)); |
| 157 DCHECK(result) << "TimedWait() should never fail with infinite timeout"; | 157 DCHECK(result) << "TimedWait() should never fail with infinite timeout"; |
| 158 } | 158 } |
| 159 | 159 |
| 160 bool WaitableEvent::TimedWait(const TimeDelta& max_time) { | 160 bool WaitableEvent::TimedWait(const TimeDelta& max_time) { |
| 161 base::ThreadRestrictions::AssertWaitAllowed(); | 161 base::ThreadRestrictions::AssertWaitAllowed(); |
| 162 const Time end_time(Time::Now() + max_time); | 162 const TimeTicks end_time(TimeTicks::Now() + max_time); |
| 163 const bool finite_time = max_time.ToInternalValue() >= 0; | 163 const bool finite_time = max_time.ToInternalValue() >= 0; |
| 164 | 164 |
| 165 kernel_->lock_.Acquire(); | 165 kernel_->lock_.Acquire(); |
| 166 if (kernel_->signaled_) { | 166 if (kernel_->signaled_) { |
| 167 if (!kernel_->manual_reset_) { | 167 if (!kernel_->manual_reset_) { |
| 168 // In this case we were signaled when we had no waiters. Now that | 168 // In this case we were signaled when we had no waiters. Now that |
| 169 // someone has waited upon us, we can automatically reset. | 169 // someone has waited upon us, we can automatically reset. |
| 170 kernel_->signaled_ = false; | 170 kernel_->signaled_ = false; |
| 171 } | 171 } |
| 172 | 172 |
| 173 kernel_->lock_.Release(); | 173 kernel_->lock_.Release(); |
| 174 return true; | 174 return true; |
| 175 } | 175 } |
| 176 | 176 |
| 177 SyncWaiter sw; | 177 SyncWaiter sw; |
| 178 sw.lock()->Acquire(); | 178 sw.lock()->Acquire(); |
| 179 | 179 |
| 180 Enqueue(&sw); | 180 Enqueue(&sw); |
| 181 kernel_->lock_.Release(); | 181 kernel_->lock_.Release(); |
| 182 // We are violating locking order here by holding the SyncWaiter lock but not | 182 // We are violating locking order here by holding the SyncWaiter lock but not |
| 183 // the WaitableEvent lock. However, this is safe because we don't lock @lock_ | 183 // the WaitableEvent lock. However, this is safe because we don't lock @lock_ |
| 184 // again before unlocking it. | 184 // again before unlocking it. |
| 185 | 185 |
| 186 for (;;) { | 186 for (;;) { |
| 187 const Time current_time(Time::Now()); | 187 const TimeTicks current_time(TimeTicks::Now()); |
| 188 | 188 |
| 189 if (sw.fired() || (finite_time && current_time >= end_time)) { | 189 if (sw.fired() || (finite_time && current_time >= end_time)) { |
| 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(); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 return true; | 398 return true; |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 | 401 |
| 402 return false; | 402 return false; |
| 403 } | 403 } |
| 404 | 404 |
| 405 // ----------------------------------------------------------------------------- | 405 // ----------------------------------------------------------------------------- |
| 406 | 406 |
| 407 } // namespace base | 407 } // namespace base |
| OLD | NEW |