diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef7d339..e020664 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,15 +81,16 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] + rust: [nightly, stable] steps: - uses: actions/checkout@v4 - name: Install Rust - run: rustup update stable + run: rustup update ${{ matrix.rust }} - name: Install cross uses: taiki-e/install-action@cross - name: Add rust-src if: startsWith(matrix.rust, 'nightly') - run: rustup component add rust-src + run: rustup +nightly component add rust-src # We don't test BSDs, since we already test them in Cirrus. - name: Android if: startsWith(matrix.os, 'ubuntu') @@ -121,11 +122,13 @@ jobs: cargo check --target x86_64-unknown-redox - name: HermitOS if: startsWith(matrix.rust, 'nightly') && matrix.os == 'ubuntu-latest' - run: | - cargo -Zbuild-std check --target x86_64-unknown-hermit + run: cargo +nightly check -Z build-std --target x86_64-unknown-hermit - name: Check haiku if: startsWith(matrix.rust, 'nightly') && matrix.os == 'ubuntu-latest' - run: cargo check -Z build-std --target x86_64-unknown-haiku + run: cargo +nightly check -Z build-std --target x86_64-unknown-haiku + - name: Check vita + if: startsWith(matrix.rust, 'nightly') && matrix.os == 'ubuntu-latest' + run: cargo +nightly check -Z build-std --target armv7-sony-vita-newlibeabihf wine: runs-on: ubuntu-22.04 diff --git a/Cargo.toml b/Cargo.toml index 5730302..6206c6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,4 +55,6 @@ socket2 = "0.5.5" [target.'cfg(unix)'.dev-dependencies] libc = "0.2" + +[target.'cfg(all(unix, not(target_os="vita")))'.dev-dependencies] signal-hook = "0.3.17" diff --git a/src/lib.rs b/src/lib.rs index 1be752b..018f2e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -402,7 +402,7 @@ impl Event { /// Tells if this event is the result of a connection failure. /// - /// This function checks if an error exist,particularlly useful in detecting if TCP connection failed. It corresponds to the `EPOLLERR` event in Linux + /// This function checks if an error exist, particularly useful in detecting if TCP connection failed. It corresponds to the `EPOLLERR` event in Linux /// and `CONNECT_FAILED` event in Windows IOCP. /// /// ## Caveats diff --git a/src/os/iocp.rs b/src/os/iocp.rs index bc37843..3370118 100644 --- a/src/os/iocp.rs +++ b/src/os/iocp.rs @@ -1,4 +1,4 @@ -//! Functionality that is only availale for IOCP-based platforms. +//! Functionality that is only available for IOCP-based platforms. pub use crate::sys::CompletionPacket; diff --git a/src/poll.rs b/src/poll.rs index 13c742e..45407c7 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -685,7 +685,7 @@ mod notify { self.read_pipe.as_fd() } - /// Provides the poll flags to be used when registering the read half of the botify pipe with the `Poller`. + /// Provides the poll flags to be used when registering the read half of the notify pipe with the `Poller`. pub(super) fn poll_flags(&self) -> PollFlags { PollFlags::RDNORM } @@ -699,7 +699,25 @@ mod notify { /// Pops a notification (if any) from the pipe. pub(super) fn pop_notification(&self) -> Result<(), io::Error> { - read(&self.read_pipe, &mut [0; 1])?; + // Pipes on Vita do not guarantee that after `write` call succeeds, the + // data becomes immediately available for reading on the other side of the pipe. + // To ensure that the notification is not lost, the read side of the pipe is temporarily + // switched to blocking for a single `read` call. + #[cfg(target_os = "vita")] + rustix::fs::fcntl_setfl( + &self.read_pipe, + rustix::fs::fcntl_getfl(&self.read_pipe)? & !rustix::fs::OFlags::NONBLOCK, + )?; + + let result = read(&self.read_pipe, &mut [0; 1]); + + #[cfg(target_os = "vita")] + rustix::fs::fcntl_setfl( + &self.read_pipe, + rustix::fs::fcntl_getfl(&self.read_pipe)? | rustix::fs::OFlags::NONBLOCK, + )?; + + result?; Ok(()) } @@ -729,7 +747,7 @@ mod notify { /// A notification pipe. /// - /// This implementation uses ther `eventfd` syscall to send notifications. + /// This implementation uses the `eventfd` syscall to send notifications. #[derive(Debug)] pub(super) struct Notify { /// The file descriptor of the eventfd object. This is also stored as the first diff --git a/tests/concurrent_modification.rs b/tests/concurrent_modification.rs index ab3e5fb..f4598c0 100644 --- a/tests/concurrent_modification.rs +++ b/tests/concurrent_modification.rs @@ -76,7 +76,7 @@ fn concurrent_modify() -> io::Result<()> { Ok(()) } -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "vita")))] #[test] fn concurrent_interruption() -> io::Result<()> { struct MakeItSend(T);