From 099c9c8da9554e80744b23a49c915631a8fe4672 Mon Sep 17 00:00:00 2001 From: Nikolay Arhipov Date: Wed, 18 Oct 2023 10:53:26 +0300 Subject: [PATCH 1/2] Added support for vita target --- Cargo.toml | 4 ++-- README.md | 4 ++-- src/sys/unix/mod.rs | 1 + src/sys/unix/net.rs | 12 +++++++++++- src/sys/unix/pipe.rs | 6 ++++-- src/sys/unix/tcp.rs | 9 +++++++-- src/sys/unix/uds/listener.rs | 10 ++++++++-- src/sys/unix/uds/mod.rs | 7 +++++-- src/sys/unix/waker.rs | 1 + 9 files changed, 41 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f54c7b63d..20842e89f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ net = [] log = { version = "0.4.8", optional = true } [target.'cfg(unix)'.dependencies] -libc = "0.2.121" +libc = "0.2.149" [target.'cfg(windows)'.dependencies.windows-sys] version = "0.48" @@ -60,7 +60,7 @@ features = [ [target.'cfg(target_os = "wasi")'.dependencies] wasi = "0.11.0" -libc = "0.2.121" +libc = "0.2.149" [dev-dependencies] env_logger = { version = "0.9.3", default-features = false } diff --git a/README.md b/README.md index 7c513863c..39dae3873 100644 --- a/README.md +++ b/README.md @@ -162,11 +162,11 @@ This uses the Windows AFD system to access socket readiness events. ## Unsupported flags -Mio uses different implementations to support the same functionality dependening +Mio uses different implementations to support the same functionality depending on the platform. Mio generally uses the "best" implementation possible, where "best" usually means most efficient for Mio's use case. However this means that the implementation is often specific to a limited number of platforms, meaning -we often have multiple implemetations for the same functionality. In some cases +we often have multiple implementations for the same functionality. In some cases it might be required to not use the "best" implementation, but another implementation Mio supports (on other platforms). **Mio does not officially support secondary implementations on platforms**, however we do have various cfg diff --git a/src/sys/unix/mod.rs b/src/sys/unix/mod.rs index eb268b9f4..5cbc10ff4 100644 --- a/src/sys/unix/mod.rs +++ b/src/sys/unix/mod.rs @@ -105,6 +105,7 @@ cfg_os_poll! { target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "vita", ))] pub(crate) mod pipe; } diff --git a/src/sys/unix/net.rs b/src/sys/unix/net.rs index 81b53a388..75f015c2f 100644 --- a/src/sys/unix/net.rs +++ b/src/sys/unix/net.rs @@ -51,13 +51,14 @@ pub(crate) fn new_socket(domain: libc::c_int, socket_type: libc::c_int) -> io::R target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", ))] { if let Err(err) = syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK)) { let _ = syscall!(close(socket)); return Err(err); } - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] if let Err(err) = syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC)) { let _ = syscall!(close(socket)); return Err(err); @@ -97,7 +98,10 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_ sin_family: libc::AF_INET as libc::sa_family_t, sin_port: addr.port().to_be(), sin_addr, + #[cfg(not(target_os = "vita"))] sin_zero: [0; 8], + #[cfg(target_os = "vita")] + sin_zero: [0; 6], #[cfg(any( target_os = "aix", target_os = "dragonfly", @@ -109,8 +113,11 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_ target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", ))] sin_len: 0, + #[cfg(target_os = "vita")] + sin_vport: addr.port().to_be(), }; let sockaddr = SocketAddrCRepr { v4: sockaddr_in }; @@ -137,8 +144,11 @@ pub(crate) fn socket_addr(addr: &SocketAddr) -> (SocketAddrCRepr, libc::socklen_ target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", ))] sin6_len: 0, + #[cfg(target_os = "vita")] + sin6_vport: addr.port().to_be(), #[cfg(target_os = "illumos")] __sin6_src_id: 0, }; diff --git a/src/sys/unix/pipe.rs b/src/sys/unix/pipe.rs index 8e92dd37d..4defd588c 100644 --- a/src/sys/unix/pipe.rs +++ b/src/sys/unix/pipe.rs @@ -17,6 +17,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> { target_os = "openbsd", target_os = "illumos", target_os = "redox", + target_os = "vita", ))] unsafe { if libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC | libc::O_NONBLOCK) != 0 { @@ -67,6 +68,7 @@ pub(crate) fn new_raw() -> io::Result<[RawFd; 2]> { target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", )))] compile_error!("unsupported target for `mio::unix::pipe`"); @@ -556,7 +558,7 @@ impl IntoRawFd for Receiver { } } -#[cfg(not(target_os = "illumos"))] +#[cfg(not(any(target_os = "illumos", target_os = "vita")))] fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { let value = nonblocking as libc::c_int; if unsafe { libc::ioctl(fd, libc::FIONBIO, &value) } == -1 { @@ -566,7 +568,7 @@ fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { } } -#[cfg(target_os = "illumos")] +#[cfg(any(target_os = "illumos", target_os = "vita"))] fn set_nonblocking(fd: RawFd, nonblocking: bool) -> io::Result<()> { let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) }; if flags < 0 { diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs index c0bc40ad1..130f4d685 100644 --- a/src/sys/unix/tcp.rs +++ b/src/sys/unix/tcp.rs @@ -89,6 +89,7 @@ pub(crate) fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", all(target_arch = "x86", target_os = "android"), ))] let stream = { @@ -99,11 +100,15 @@ pub(crate) fn accept(listener: &net::TcpListener) -> io::Result<(net::TcpStream, )) .map(|socket| unsafe { net::TcpStream::from_raw_fd(socket) }) .and_then(|s| { - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] syscall!(fcntl(s.as_raw_fd(), libc::F_SETFD, libc::FD_CLOEXEC))?; // See https://github.com/tokio-rs/mio/issues/1450 - #[cfg(any(all(target_arch = "x86", target_os = "android"), target_os = "espidf",))] + #[cfg(any( + all(target_arch = "x86", target_os = "android"), + target_os = "espidf", + target_os = "vita", + ))] syscall!(fcntl(s.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK))?; Ok(s) diff --git a/src/sys/unix/uds/listener.rs b/src/sys/unix/uds/listener.rs index ff77c53bd..65d332c83 100644 --- a/src/sys/unix/uds/listener.rs +++ b/src/sys/unix/uds/listener.rs @@ -52,6 +52,7 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", // Android x86's seccomp profile forbids calls to `accept4(2)` // See https://github.com/tokio-rs/mio/issues/1445 for details all(target_arch = "x86", target_os = "android"), @@ -76,6 +77,7 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", all(target_arch = "x86", target_os = "android") ))] let socket = syscall!(accept( @@ -87,11 +89,15 @@ pub(crate) fn accept(listener: &net::UnixListener) -> io::Result<(UnixStream, So // Ensure the socket is closed if either of the `fcntl` calls // error below. let s = unsafe { net::UnixStream::from_raw_fd(socket) }; - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC))?; // See https://github.com/tokio-rs/mio/issues/1450 - #[cfg(any(all(target_arch = "x86", target_os = "android"), target_os = "espidf",))] + #[cfg(any( + all(target_arch = "x86", target_os = "android"), + target_os = "espidf", + target_os = "vita", + ))] syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK))?; Ok(s) diff --git a/src/sys/unix/uds/mod.rs b/src/sys/unix/uds/mod.rs index 20b668f80..376ee05ee 100644 --- a/src/sys/unix/uds/mod.rs +++ b/src/sys/unix/uds/mod.rs @@ -81,6 +81,7 @@ cfg_os_poll! { target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", )))] let flags = flags | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC; @@ -101,15 +102,17 @@ cfg_os_poll! { target_os = "tvos", target_os = "watchos", target_os = "espidf", + target_os = "vita", ))] { syscall!(fcntl(fds[0], libc::F_SETFL, libc::O_NONBLOCK))?; - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] syscall!(fcntl(fds[0], libc::F_SETFD, libc::FD_CLOEXEC))?; syscall!(fcntl(fds[1], libc::F_SETFL, libc::O_NONBLOCK))?; - #[cfg(not(target_os = "espidf"))] + #[cfg(not(any(target_os = "espidf", target_os = "vita")))] syscall!(fcntl(fds[1], libc::F_SETFD, libc::FD_CLOEXEC))?; } + Ok(pair) } diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs index 4b73df32d..2e1e3559e 100644 --- a/src/sys/unix/waker.rs +++ b/src/sys/unix/waker.rs @@ -285,6 +285,7 @@ mod pipe { target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "vita", ) ))] pub(crate) use self::pipe::WakerInternal; From c1705f923a5497cc83cfbbb12986eba639ee05c1 Mon Sep 17 00:00:00 2001 From: Nikolay Arhipov Date: Wed, 18 Oct 2023 18:23:02 +0300 Subject: [PATCH 2/2] Enabled Vita without cfg in RUSTFLAGS and added CI checks --- .github/workflows/ci.yml | 17 ++++++++++++++++ src/poll.rs | 9 +++++---- src/sys/unix/mod.rs | 6 +++--- src/sys/unix/selector/mod.rs | 4 ++-- src/sys/unix/waker.rs | 39 ++++++++++++++++++++---------------- 5 files changed, 49 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 490e8fedd..787624836 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -133,6 +133,22 @@ jobs: run: cargo install --debug cargo-hack - name: Check all targets run: make check_all_targets + CheckTier3Targets: + name: Check + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + target: ["armv7-sony-vita-newlibeabihf"] + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rust-src + - uses: taiki-e/install-action@cargo-hack + - name: Run check + run: cargo hack check -Z build-std=std,panic_abort --feature-powerset --target ${{ matrix.target }} Sanitizer: runs-on: ubuntu-latest timeout-minutes: 10 @@ -160,5 +176,6 @@ jobs: - Docs - Rustfmt - CheckTargets + - CheckTier3Targets steps: - run: exit 0 diff --git a/src/poll.rs b/src/poll.rs index d904eb97c..0a7b4bedf 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -1,4 +1,4 @@ -#[cfg(all(unix, not(mio_unsupported_force_poll_poll)))] +#[cfg(all(unix, not(mio_unsupported_force_poll_poll), not(target_os = "vita")))] use std::os::unix::io::{AsRawFd, RawFd}; #[cfg(all(debug_assertions, not(target_os = "wasi")))] use std::sync::atomic::{AtomicBool, Ordering}; @@ -423,7 +423,7 @@ impl Poll { } } -#[cfg(all(unix, not(mio_unsupported_force_poll_poll)))] +#[cfg(all(unix, not(mio_unsupported_force_poll_poll), not(target_os = "vita")))] impl AsRawFd for Poll { fn as_raw_fd(&self) -> RawFd { self.registry.as_raw_fd() @@ -710,7 +710,7 @@ impl fmt::Debug for Registry { } } -#[cfg(all(unix, not(mio_unsupported_force_poll_poll)))] +#[cfg(all(unix, not(mio_unsupported_force_poll_poll), not(target_os = "vita")))] impl AsRawFd for Registry { fn as_raw_fd(&self) -> RawFd { self.selector.as_raw_fd() @@ -720,7 +720,8 @@ impl AsRawFd for Registry { cfg_os_poll! { #[cfg(all( unix, - not(mio_unsupported_force_poll_poll) + not(mio_unsupported_force_poll_poll), + not(target_os = "vita"), ))] #[test] pub fn as_raw_fd() { diff --git a/src/sys/unix/mod.rs b/src/sys/unix/mod.rs index 5cbc10ff4..7804236da 100644 --- a/src/sys/unix/mod.rs +++ b/src/sys/unix/mod.rs @@ -34,7 +34,7 @@ cfg_os_poll! { cfg_io_source! { // Both `kqueue` and `epoll` don't need to hold any user space state. - #[cfg(not(mio_unsupported_force_poll_poll))] + #[cfg(not(any(mio_unsupported_force_poll_poll, target_os = "vita")))] mod stateless_io_source { use std::io; use std::os::unix::io::RawFd; @@ -87,10 +87,10 @@ cfg_os_poll! { } } - #[cfg(not(mio_unsupported_force_poll_poll))] + #[cfg(not(any(mio_unsupported_force_poll_poll, target_os = "vita")))] pub(crate) use self::stateless_io_source::IoSourceState; - #[cfg(mio_unsupported_force_poll_poll)] + #[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))] pub(crate) use self::selector::IoSourceState; } diff --git a/src/sys/unix/selector/mod.rs b/src/sys/unix/selector/mod.rs index 7fa73b8d6..30a74cb07 100644 --- a/src/sys/unix/selector/mod.rs +++ b/src/sys/unix/selector/mod.rs @@ -20,10 +20,10 @@ mod epoll; ))] pub(crate) use self::epoll::{event, Event, Events, Selector}; -#[cfg(mio_unsupported_force_poll_poll)] +#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))] mod poll; -#[cfg(mio_unsupported_force_poll_poll)] +#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))] pub(crate) use self::poll::{event, Event, Events, IoSourceState, Selector}; #[cfg(all( diff --git a/src/sys/unix/waker.rs b/src/sys/unix/waker.rs index 2e1e3559e..06f655e02 100644 --- a/src/sys/unix/waker.rs +++ b/src/sys/unix/waker.rs @@ -9,7 +9,8 @@ target_os = "tvos", target_os = "watchos", ) - )) + )), + not(target_os = "vita"), ))] mod fdbased { #[cfg(all( @@ -61,7 +62,8 @@ mod fdbased { target_os = "tvos", target_os = "watchos", ) - )) + )), + not(target_os = "vita"), ))] pub use self::fdbased::Waker; @@ -205,6 +207,7 @@ pub use self::kqueue::Waker; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "vita", ))] mod pipe { use crate::sys::unix::pipe; @@ -250,7 +253,7 @@ mod pipe { } } - #[cfg(mio_unsupported_force_poll_poll)] + #[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))] pub fn ack_and_reset(&self) { self.empty(); } @@ -275,22 +278,24 @@ mod pipe { } } -#[cfg(all( - mio_unsupported_force_poll_poll, - any( - mio_unsupported_force_waker_pipe, - target_os = "aix", - target_os = "dragonfly", - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_os = "vita", - ) +#[cfg(any( + all( + mio_unsupported_force_poll_poll, + any( + mio_unsupported_force_waker_pipe, + target_os = "aix", + target_os = "dragonfly", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + ) + ), + target_os = "vita", ))] pub(crate) use self::pipe::WakerInternal; -#[cfg(mio_unsupported_force_poll_poll)] +#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))] mod poll { use crate::sys::Selector; use crate::Token; @@ -316,5 +321,5 @@ mod poll { } } -#[cfg(mio_unsupported_force_poll_poll)] +#[cfg(any(mio_unsupported_force_poll_poll, target_os = "vita"))] pub use self::poll::Waker;