mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
sys_util: remove deprecated Poller/Pollable interface
Now that there are no users of that interface, we should remove it. TEST=./build_test BUG=chromium:816692 Change-Id: Ifdbde22984f557b945e49559ba47076e99db923b Reviewed-on: https://chromium-review.googlesource.com/1000103 Commit-Ready: Zach Reizner <zachr@chromium.org> Tested-by: Zach Reizner <zachr@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
parent
d86e698ec8
commit
4fcd1af11e
5 changed files with 5 additions and 214 deletions
|
@ -18,7 +18,7 @@ use std::str::FromStr;
|
|||
|
||||
use libc::EPERM;
|
||||
|
||||
use sys_util::{Error as SysError, Pollable};
|
||||
use sys_util::{Error as SysError};
|
||||
use sys_util::{ioctl_with_val, ioctl_with_ref, ioctl_with_mut_ref};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -160,7 +160,7 @@ pub struct Tap {
|
|||
if_name: [u8; 16usize],
|
||||
}
|
||||
|
||||
pub trait TapT: Read + Write + AsRawFd + Pollable + Send + Sized {
|
||||
pub trait TapT: Read + Write + AsRawFd + Send + Sized {
|
||||
/// Create a new tap interface. Set the `vnet_hdr` flag to true to allow offloading on this tap,
|
||||
/// which will add an extra 12 byte virtio net header to incoming frames. Offloading cannot
|
||||
/// be used if `vnet_hdr` is false.
|
||||
|
@ -449,14 +449,6 @@ impl AsRawFd for Tap {
|
|||
}
|
||||
}
|
||||
|
||||
// Safe since the tap fd's lifetime lasts as long as this trait object, and the
|
||||
// tap fd is pollable.
|
||||
unsafe impl Pollable for Tap {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.tap_file.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod fakes {
|
||||
use super::*;
|
||||
use std::fs::OpenOptions;
|
||||
|
@ -549,12 +541,6 @@ pub mod fakes {
|
|||
self.tap_file.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Pollable for FakeTap {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.tap_file.as_raw_fd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -97,12 +97,6 @@ impl IntoRawFd for EventFd {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl ::Pollable for EventFd {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.eventfd.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -9,152 +9,18 @@ use std::i32;
|
|||
use std::i64;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::unix::io::{RawFd, AsRawFd, IntoRawFd, FromRawFd};
|
||||
use std::os::unix::net::{UnixDatagram, UnixStream};
|
||||
use std::ptr::{null, null_mut};
|
||||
use std::ptr::null_mut;
|
||||
use std::slice;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use libc::{c_int, c_long, timespec, time_t, nfds_t, sigset_t, pollfd, syscall, SYS_ppoll, POLLIN,
|
||||
POLLHUP, EPOLL_CLOEXEC, EPOLLIN, EPOLLHUP, EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL,
|
||||
use libc::{c_int, EPOLL_CLOEXEC, EPOLLIN, EPOLLHUP, EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL,
|
||||
epoll_create1, epoll_ctl, epoll_wait, epoll_event};
|
||||
|
||||
use {Result, errno_result};
|
||||
|
||||
const POLL_CONTEXT_MAX_EVENTS: usize = 16;
|
||||
|
||||
// The libc wrapper suppresses the kernel's changes to timeout, so we use the syscall directly.
|
||||
unsafe fn ppoll(fds: *mut pollfd,
|
||||
nfds: nfds_t,
|
||||
timeout: *mut timespec,
|
||||
sigmask: *const sigset_t,
|
||||
sigsetsize: usize)
|
||||
-> c_int {
|
||||
syscall(SYS_ppoll, fds, nfds, timeout, sigmask, sigsetsize) as c_int
|
||||
}
|
||||
|
||||
/// Trait for file descriptors that can be polled for input.
|
||||
///
|
||||
/// This is marked unsafe because the implementation must promise that the returned RawFd is valid
|
||||
/// for polling purposes and that the lifetime of the returned fd is at least that of the trait
|
||||
/// object.
|
||||
pub unsafe trait Pollable {
|
||||
/// Gets the file descriptor that can be polled for input.
|
||||
fn pollable_fd(&self) -> RawFd;
|
||||
}
|
||||
|
||||
unsafe impl Pollable for UnixStream {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Pollable for UnixDatagram {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Pollable for File {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to poll multiple `Pollable` objects at once.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use sys_util::{Result, EventFd, Poller, Pollable};
|
||||
/// # fn test() -> Result<()> {
|
||||
/// let evt1 = EventFd::new()?;
|
||||
/// let evt2 = EventFd::new()?;
|
||||
/// evt2.write(1)?;
|
||||
///
|
||||
/// let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];
|
||||
///
|
||||
/// let mut poller = Poller::new(2);
|
||||
/// assert_eq!(poller.poll(&pollables[..]), Ok([2].as_ref()));
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct Poller {
|
||||
pollfds: Vec<pollfd>,
|
||||
tokens: Vec<u32>,
|
||||
}
|
||||
|
||||
impl Poller {
|
||||
/// Constructs a new poller object with the given `capacity` of Pollable objects pre-allocated.
|
||||
pub fn new(capacity: usize) -> Poller {
|
||||
Poller {
|
||||
pollfds: Vec::with_capacity(capacity),
|
||||
tokens: Vec::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
|
||||
/// Waits for any of the given slice of `token`-`Pollable` tuples to be readable without
|
||||
/// blocking and returns the `token` of each that is readable.
|
||||
///
|
||||
/// This is guaranteed to not allocate if `pollables.len()` is less than the `capacity` given in
|
||||
/// `Poller::new`.
|
||||
pub fn poll(&mut self, pollables: &[(u32, &Pollable)]) -> Result<&[u32]> {
|
||||
self.poll_timeout(pollables, &mut Duration::new(time_t::max_value() as u64, 0))
|
||||
}
|
||||
|
||||
/// Waits for up to the given timeout for any of the given slice of `token`-`Pollable` tuples to
|
||||
/// be readable without blocking and returns the `token` of each that is readable.
|
||||
///
|
||||
/// If a timeout duration is given, the duration will be modified to the unused portion of the
|
||||
/// timeout, even if an error is returned.
|
||||
///
|
||||
/// This is guaranteed to not allocate if `pollables.len()` is less than the `capacity` given in
|
||||
/// `Poller::new`.
|
||||
pub fn poll_timeout(&mut self,
|
||||
pollables: &[(u32, &Pollable)],
|
||||
timeout: &mut Duration)
|
||||
-> Result<&[u32]> {
|
||||
self.pollfds.clear();
|
||||
for pollable in pollables.iter() {
|
||||
self.pollfds
|
||||
.push(pollfd {
|
||||
fd: pollable.1.pollable_fd(),
|
||||
events: POLLIN,
|
||||
revents: 0,
|
||||
});
|
||||
}
|
||||
|
||||
let mut timeout_spec = timespec {
|
||||
tv_sec: timeout.as_secs() as time_t,
|
||||
tv_nsec: timeout.subsec_nanos() as c_long,
|
||||
};
|
||||
// Safe because poll is given the correct length of properly initialized pollfds, and we
|
||||
// check the return result.
|
||||
let ret = unsafe {
|
||||
handle_eintr_errno!(ppoll(self.pollfds.as_mut_ptr(),
|
||||
self.pollfds.len() as nfds_t,
|
||||
&mut timeout_spec,
|
||||
null(),
|
||||
0))
|
||||
};
|
||||
|
||||
*timeout = Duration::new(timeout_spec.tv_sec as u64, timeout_spec.tv_nsec as u32);
|
||||
|
||||
if ret < 0 {
|
||||
return errno_result();
|
||||
}
|
||||
|
||||
self.tokens.clear();
|
||||
for (pollfd, pollable) in self.pollfds.iter().zip(pollables.iter()) {
|
||||
if (pollfd.revents & (POLLIN | POLLHUP)) != 0 {
|
||||
self.tokens.push(pollable.0);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(&self.tokens)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for a token that can be associated with an `fd` in a `PollContext`.
|
||||
///
|
||||
/// Simple enums that have no or primitive variant data data can use the `#[derive(PollToken)]`
|
||||
|
@ -590,49 +456,9 @@ impl<T: PollToken> IntoRawFd for PollContext<T> {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use std::time::Instant;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use EventFd;
|
||||
|
||||
#[test]
|
||||
fn poller() {
|
||||
let evt1 = EventFd::new().unwrap();
|
||||
let evt2 = EventFd::new().unwrap();
|
||||
evt2.write(1).unwrap();
|
||||
|
||||
let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];
|
||||
|
||||
let mut poller = Poller::new(2);
|
||||
assert_eq!(poller.poll(&pollables[..]), Ok([2].as_ref()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poller_multi() {
|
||||
let evt1 = EventFd::new().unwrap();
|
||||
let evt2 = EventFd::new().unwrap();
|
||||
evt1.write(1).unwrap();
|
||||
evt2.write(1).unwrap();
|
||||
|
||||
let pollables: Vec<(u32, &Pollable)> = vec![(1, &evt1), (2, &evt2)];
|
||||
|
||||
let mut poller = Poller::new(2);
|
||||
assert_eq!(poller.poll(&pollables[..]), Ok([1, 2].as_ref()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timeout() {
|
||||
let evt1 = EventFd::new().unwrap();
|
||||
let initial_dur = Duration::from_millis(10);
|
||||
let mut timeout_dur = initial_dur;
|
||||
let mut poller = Poller::new(0);
|
||||
assert_eq!(poller.poll_timeout(&[(1, &evt1)], &mut timeout_dur),
|
||||
Ok([].as_ref()));
|
||||
assert_eq!(timeout_dur, Duration::from_secs(0));
|
||||
evt1.write(1).unwrap();
|
||||
timeout_dur = initial_dur;
|
||||
assert_eq!(poller.poll_timeout(&[(1, &evt1)], &mut timeout_dur),
|
||||
Ok([1].as_ref()));
|
||||
assert!(timeout_dur < initial_dur);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn poll_context() {
|
||||
let evt1 = EventFd::new().unwrap();
|
||||
|
|
|
@ -100,14 +100,6 @@ impl SignalFd {
|
|||
}
|
||||
}
|
||||
|
||||
// Safe since the signalfd lifetime lasts as long as this trait object, and the
|
||||
// signalfd is pollable.
|
||||
unsafe impl ::Pollable for SignalFd {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.signalfd.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for SignalFd {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.signalfd.as_raw_fd()
|
||||
|
|
|
@ -111,10 +111,3 @@ unsafe impl<'a> Terminal for StdinLock<'a> {
|
|||
STDIN_FILENO
|
||||
}
|
||||
}
|
||||
|
||||
// Safe because we return a genuine pollable fd that never changes and shares our lifetime.
|
||||
unsafe impl<T: Terminal> ::Pollable for T {
|
||||
fn pollable_fd(&self) -> RawFd {
|
||||
self.tty_fd()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue