fix(wasi): enable all WasiFiles to be pollable (#3913)
Currently, the use of the downcast method means that you have to use one of the hard-coded types. But Enarx needs to define its own `WasiFile` implementations. This works fine, except the resulting files cannot be used in poll because they aren't part of the hard-coded list. Replace this with an accessor method for the pollable type in `WasiFile`. Because we provide a default implementation of the method and manually implement it on all the hard-coded types, this is backwards compatible. Signed-off-by: Nathaniel McCallum <nathaniel@profian.com>
This commit is contained in:
committed by
GitHub
parent
13b9396931
commit
0df4e961c0
@@ -1,15 +1,8 @@
|
||||
use cap_std::time::Duration;
|
||||
use io_lifetimes::{AsFd, BorrowedFd};
|
||||
use rustix::io::{PollFd, PollFlags};
|
||||
use std::convert::TryInto;
|
||||
use wasi_common::{
|
||||
file::WasiFile,
|
||||
sched::{
|
||||
subscription::{RwEventFlags, Subscription},
|
||||
Poll,
|
||||
},
|
||||
Error, ErrorExt,
|
||||
};
|
||||
use wasi_common::sched::subscription::{RwEventFlags, Subscription};
|
||||
use wasi_common::{sched::Poll, Error, ErrorExt};
|
||||
|
||||
pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> {
|
||||
if poll.is_empty() {
|
||||
@@ -19,16 +12,18 @@ pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> {
|
||||
for s in poll.rw_subscriptions() {
|
||||
match s {
|
||||
Subscription::Read(f) => {
|
||||
let fd = wasi_file_fd(f.file).ok_or(
|
||||
Error::invalid_argument().context("read subscription fd downcast failed"),
|
||||
)?;
|
||||
let fd = f
|
||||
.file
|
||||
.pollable()
|
||||
.ok_or(Error::invalid_argument().context("file is not pollable"))?;
|
||||
pollfds.push(PollFd::from_borrowed_fd(fd, PollFlags::IN));
|
||||
}
|
||||
|
||||
Subscription::Write(f) => {
|
||||
let fd = wasi_file_fd(f.file).ok_or(
|
||||
Error::invalid_argument().context("write subscription fd downcast failed"),
|
||||
)?;
|
||||
let fd = f
|
||||
.file
|
||||
.pollable()
|
||||
.ok_or(Error::invalid_argument().context("file is not pollable"))?;
|
||||
pollfds.push(PollFd::from_borrowed_fd(fd, PollFlags::OUT));
|
||||
}
|
||||
Subscription::MonotonicClock { .. } => unreachable!(),
|
||||
@@ -85,30 +80,3 @@ pub async fn poll_oneoff<'a>(poll: &mut Poll<'a>) -> Result<(), Error> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn wasi_file_fd(f: &dyn WasiFile) -> Option<BorrowedFd<'_>> {
|
||||
let a = f.as_any();
|
||||
if a.is::<crate::file::File>() {
|
||||
Some(a.downcast_ref::<crate::file::File>().unwrap().as_fd())
|
||||
} else if a.is::<crate::net::TcpStream>() {
|
||||
Some(a.downcast_ref::<crate::net::TcpStream>().unwrap().as_fd())
|
||||
} else if a.is::<crate::net::TcpListener>() {
|
||||
Some(a.downcast_ref::<crate::net::TcpListener>().unwrap().as_fd())
|
||||
} else if a.is::<crate::net::UnixStream>() {
|
||||
Some(a.downcast_ref::<crate::net::UnixStream>().unwrap().as_fd())
|
||||
} else if a.is::<crate::net::UnixListener>() {
|
||||
Some(
|
||||
a.downcast_ref::<crate::net::UnixListener>()
|
||||
.unwrap()
|
||||
.as_fd(),
|
||||
)
|
||||
} else if a.is::<crate::stdio::Stdin>() {
|
||||
Some(a.downcast_ref::<crate::stdio::Stdin>().unwrap().as_fd())
|
||||
} else if a.is::<crate::stdio::Stdout>() {
|
||||
Some(a.downcast_ref::<crate::stdio::Stdout>().unwrap().as_fd())
|
||||
} else if a.is::<crate::stdio::Stderr>() {
|
||||
Some(a.downcast_ref::<crate::stdio::Stderr>().unwrap().as_fd())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user