Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/base_tokio/src/sys/linux/event.rs
5394 views
1
// Copyright 2024 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 std::os::fd::AsRawFd;
6
7
use tokio::io::unix::AsyncFd;
8
9
/// An async version of `base::Event`.
10
pub struct EventTokio(AsyncFd<base::SafeDescriptor>);
11
12
impl EventTokio {
13
/// WARNING: Sets O_NONBLOCK internally, which will also affect all clones of the `Event`.
14
pub fn new(event: base::Event) -> anyhow::Result<Self> {
15
let fd: base::SafeDescriptor = event.into();
16
base::add_fd_flags(fd.as_raw_fd(), libc::O_NONBLOCK)?;
17
Ok(Self(AsyncFd::new(fd)?))
18
}
19
20
/// Blocks until the event is signaled and clears the signal.
21
///
22
/// It is undefined behavior to wait on an event from multiple threads or processes
23
/// simultaneously.
24
pub async fn wait(&self) -> std::io::Result<()> {
25
loop {
26
let mut guard = self.0.readable().await?;
27
let io_result = guard.try_io(|inner| {
28
let mut buf: u64 = 0;
29
// SAFETY: This is safe because we made this fd and the pointer we pass can not
30
// overflow because we give the syscall's size parameter properly.
31
let ret = unsafe {
32
libc::read(
33
inner.as_raw_fd(),
34
&mut buf as *mut u64 as *mut libc::c_void,
35
std::mem::size_of::<u64>(),
36
)
37
};
38
if ret < 0 {
39
return Err(std::io::Error::last_os_error());
40
}
41
if ret as usize != std::mem::size_of::<u64>() {
42
return Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof));
43
}
44
Ok(())
45
});
46
47
match io_result {
48
Ok(result) => return result,
49
Err(_would_block) => continue,
50
}
51
}
52
}
53
}
54
55