Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/cros_async/src/sys/linux/timer.rs
5394 views
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use base::TimerTrait;
6
7
use crate::AsyncError;
8
use crate::AsyncResult;
9
use crate::IntoAsync;
10
use crate::TimerAsync;
11
12
impl<T: TimerTrait + IntoAsync> TimerAsync<T> {
13
pub async fn wait_sys(&self) -> AsyncResult<()> {
14
let (n, _) = self
15
.io_source
16
.read_to_vec(None, 0u64.to_ne_bytes().to_vec())
17
.await?;
18
if n != 8 {
19
return Err(AsyncError::EventAsync(base::Error::new(libc::ENODATA)));
20
}
21
Ok(())
22
}
23
}
24
25
#[cfg(test)]
26
mod tests {
27
use std::sync::Arc;
28
use std::time::Duration;
29
use std::time::Instant;
30
31
use base::Timer;
32
33
use super::super::fd_executor::EpollReactor;
34
use super::super::uring_executor::UringReactor;
35
use super::*;
36
use crate::common_executor::RawExecutor;
37
use crate::sys::linux::uring_executor::is_uring_stable;
38
use crate::Executor;
39
use crate::ExecutorTrait;
40
41
impl TimerAsync<Timer> {
42
pub(crate) fn new_poll(
43
timer: Timer,
44
ex: &Arc<RawExecutor<EpollReactor>>,
45
) -> AsyncResult<TimerAsync<Timer>> {
46
ex.async_from(timer)
47
.map(|io_source| TimerAsync { io_source })
48
}
49
50
pub(crate) fn new_uring(
51
timer: Timer,
52
ex: &Arc<RawExecutor<UringReactor>>,
53
) -> AsyncResult<TimerAsync<Timer>> {
54
ex.async_from(timer)
55
.map(|io_source| TimerAsync { io_source })
56
}
57
}
58
59
#[test]
60
fn timer() {
61
async fn this_test(ex: &Executor) {
62
let dur = Duration::from_millis(200);
63
let now = Instant::now();
64
TimerAsync::sleep(ex, dur).await.expect("unable to sleep");
65
assert!(now.elapsed() >= dur);
66
}
67
68
let ex = Executor::new().expect("creating an executor failed");
69
ex.run_until(this_test(&ex)).unwrap();
70
}
71
72
#[test]
73
fn one_shot() {
74
if !is_uring_stable() {
75
return;
76
}
77
78
async fn this_test(ex: &Arc<RawExecutor<UringReactor>>) {
79
let mut tfd = Timer::new().expect("failed to create timerfd");
80
81
let dur = Duration::from_millis(200);
82
let now = Instant::now();
83
tfd.reset_oneshot(dur).expect("failed to arm timer");
84
85
let t = TimerAsync::new_uring(tfd, ex).unwrap();
86
t.wait().await.expect("unable to wait for timer");
87
88
assert!(now.elapsed() >= dur);
89
}
90
91
let ex = RawExecutor::<UringReactor>::new().unwrap();
92
ex.run_until(this_test(&ex)).unwrap();
93
}
94
95
#[test]
96
fn one_shot_fd() {
97
async fn this_test(ex: &Arc<RawExecutor<EpollReactor>>) {
98
let mut tfd = Timer::new().expect("failed to create timerfd");
99
100
let dur = Duration::from_millis(200);
101
let now = Instant::now();
102
tfd.reset_oneshot(dur).expect("failed to arm timer");
103
104
let t = TimerAsync::new_poll(tfd, ex).unwrap();
105
t.wait().await.expect("unable to wait for timer");
106
107
assert!(now.elapsed() >= dur);
108
}
109
110
let ex = RawExecutor::<EpollReactor>::new().unwrap();
111
ex.run_until(this_test(&ex)).unwrap();
112
}
113
}
114
115