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 |