1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/system/waiter.h"
9 #include "base/logging.h"
10 #include "base/time/time.h"
21 wait_result_(MOJO_RESULT_INTERNAL
) {
32 // NOTE(vtl): If performance ever becomes an issue, we can disable the setting
33 // of |wait_result_| (except the first one in |Awake()|) in Release builds.
34 wait_result_
= MOJO_RESULT_INTERNAL
;
37 // TODO(vtl): Fast-path the |deadline == 0| case?
38 MojoResult
Waiter::Wait(MojoDeadline deadline
) {
39 base::AutoLock
locker(lock_
);
43 // It'll need to be re-initialized after this.
47 // Fast-path the already-awoken case:
49 DCHECK_NE(wait_result_
, MOJO_RESULT_INTERNAL
);
53 // |MojoDeadline| is actually a |uint64_t|, but we need a signed quantity.
54 // Treat any out-of-range deadline as "forever" (which is wrong, but okay
55 // since 2^63 microseconds is ~300000 years). Note that this also takes care
56 // of the |MOJO_DEADLINE_INDEFINITE| (= 2^64 - 1) case.
57 if (deadline
> static_cast<uint64_t>(std::numeric_limits
<int64_t>::max())) {
62 // NOTE(vtl): This is very inefficient on POSIX, since pthreads condition
63 // variables take an absolute deadline.
64 const base::TimeTicks end_time
= base::TimeTicks::HighResNow() +
65 base::TimeDelta::FromMicroseconds(static_cast<int64_t>(deadline
));
67 base::TimeTicks now_time
= base::TimeTicks::HighResNow();
68 if (now_time
>= end_time
)
69 return MOJO_RESULT_DEADLINE_EXCEEDED
;
71 cv_
.TimedWait(end_time
- now_time
);
75 DCHECK_NE(wait_result_
, MOJO_RESULT_INTERNAL
);
79 void Waiter::Awake(MojoResult wait_result
) {
80 base::AutoLock
locker(lock_
);
86 wait_result_
= wait_result
;
88 // |cv_.Wait()|/|cv_.TimedWait()| will return after |lock_| is released.