Refactor poll_oneoff on *nix (#137)

* Fixes CraneStation/wasmtime#440

This commit introduces a couple of changes/fixes:
* it annotates `log::debug!` messages with "host" to differentiate
  between file descriptors stored on the WASI side (aka the wrappers)
  and those managed by the host (aka the wrapped)
* it fixes CraneStation/wasmtime#440, i.e., incorrect passing of
  file descriptor to `poll_oneoff` where currently errenously we
  pass in the wrapper instead of the wrapped value
* it adds a couple more `log::debug!` macros calls for easier future
  debugging

* Add partial refactorting to poll_oneoff

This commit lays the groundwork for more clean up to come in
subsequent commits.

* Finalise refactoring of `poll_oneoff`

* Fix compilation error on Windows

* Address majority of suggestions and refactor

Co-authored-by: Marcin Mielniczuk <marmistrz.dev@zoho.eu>

* Add poll_oneoff test case

* Leave timeout in nanoseconds in ClockEventData

Instead of converting the timeout value from nanoseconds to
milliseconds in the host-independent impl, move the conversion
to *nix-specific impl as the conversion is currently only warranted
by the POSIX `poll` syscall.

* Don't fail immediately on bad descriptor

If the user specifies an invalid descriptor inside a subscription,
don't fail immediately but rather generate an event with the thrown
WASI error code, and continue with the remaining, potentially
correct subscriptions.
This commit is contained in:
Jakub Konka
2019-10-30 09:57:59 +01:00
committed by GitHub
parent aecec187d7
commit f3a5186230
8 changed files with 209 additions and 145 deletions

View File

@@ -67,14 +67,14 @@ pub(crate) unsafe fn determine_type_rights<Fd: AsRawFd>(
let file = std::mem::ManuallyDrop::new(std::fs::File::from_raw_fd(fd.as_raw_fd()));
let ft = file.metadata()?.file_type();
if ft.is_block_device() {
log::debug!("Fd {:?} is a block device", fd.as_raw_fd());
log::debug!("Host fd {:?} is a block device", fd.as_raw_fd());
(
host::__WASI_FILETYPE_BLOCK_DEVICE,
host::RIGHTS_BLOCK_DEVICE_BASE,
host::RIGHTS_BLOCK_DEVICE_INHERITING,
)
} else if ft.is_char_device() {
log::debug!("Fd {:?} is a char device", fd.as_raw_fd());
log::debug!("Host fd {:?} is a char device", fd.as_raw_fd());
if isatty(fd)? {
(
host::__WASI_FILETYPE_CHARACTER_DEVICE,
@@ -89,21 +89,21 @@ pub(crate) unsafe fn determine_type_rights<Fd: AsRawFd>(
)
}
} else if ft.is_dir() {
log::debug!("Fd {:?} is a directory", fd.as_raw_fd());
log::debug!("Host fd {:?} is a directory", fd.as_raw_fd());
(
host::__WASI_FILETYPE_DIRECTORY,
host::RIGHTS_DIRECTORY_BASE,
host::RIGHTS_DIRECTORY_INHERITING,
)
} else if ft.is_file() {
log::debug!("Fd {:?} is a file", fd.as_raw_fd());
log::debug!("Host fd {:?} is a file", fd.as_raw_fd());
(
host::__WASI_FILETYPE_REGULAR_FILE,
host::RIGHTS_REGULAR_FILE_BASE,
host::RIGHTS_REGULAR_FILE_INHERITING,
)
} else if ft.is_socket() {
log::debug!("Fd {:?} is a socket", fd.as_raw_fd());
log::debug!("Host fd {:?} is a socket", fd.as_raw_fd());
use nix::sys::socket;
match socket::getsockopt(fd.as_raw_fd(), socket::sockopt::SockType)? {
socket::SockType::Datagram => (
@@ -119,14 +119,14 @@ pub(crate) unsafe fn determine_type_rights<Fd: AsRawFd>(
_ => return Err(Error::EINVAL),
}
} else if ft.is_fifo() {
log::debug!("Fd {:?} is a fifo", fd.as_raw_fd());
log::debug!("Host fd {:?} is a fifo", fd.as_raw_fd());
(
host::__WASI_FILETYPE_UNKNOWN,
host::RIGHTS_REGULAR_FILE_BASE,
host::RIGHTS_REGULAR_FILE_INHERITING,
)
} else {
log::debug!("Fd {:?} is unknown", fd.as_raw_fd());
log::debug!("Host fd {:?} is unknown", fd.as_raw_fd());
return Err(Error::EINVAL);
}
};