From a30710db6e7d68f5a0a364314d49f764ab0cc86f Mon Sep 17 00:00:00 2001 From: Jeron Aldaron Lau Date: Sun, 22 Jan 2023 00:10:24 -0600 Subject: [PATCH] Use `std::os::fd` --- CHANGELOG.md | 3 +++ Cargo.toml | 2 +- examples/pipe.rs | 59 ++++++++++++++++++++--------------------------- examples/sleep.rs | 33 +++++++++++--------------- src/epoll.rs | 25 +++++++++++--------- src/lib.rs | 2 +- 6 files changed, 58 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5c788..c27d906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to `smelling_salts` will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://github.com/AldaronLau/semver). +## [0.11.0] - Unreleased + + ## [0.10.0] - 2023-01-18 ### Changed - Updated `whisk` to 0.10 diff --git a/Cargo.toml b/Cargo.toml index d8c58e2..5fdfffe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ -# Copyright © 2020-2022 The Smelling Salts Contributors. +# Copyright © 2020-2023 The Smelling Salts Contributors. # # Licensed under any of: # - Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0) diff --git a/examples/pipe.rs b/examples/pipe.rs index 1a0af88..4f89208 100644 --- a/examples/pipe.rs +++ b/examples/pipe.rs @@ -1,7 +1,10 @@ use std::{ convert::TryInto, mem::{self, MaybeUninit}, - os::{raw, unix::io::RawFd}, + os::{ + fd::{AsRawFd, FromRawFd, OwnedFd, RawFd}, + raw, + }, }; use async_main::async_main; @@ -17,17 +20,16 @@ extern "C" { fn pipe2(pipefd: *mut [RawFd; 2], flags: raw::c_int) -> RawFd; fn write(fd: RawFd, buf: *const raw::c_void, count: usize) -> isize; fn read(fd: RawFd, buf: *mut raw::c_void, count: usize) -> isize; - fn close(fd: RawFd) -> raw::c_int; } /// A `PipeReceiver` device future. -pub struct PipeReceiver(Option); +pub struct PipeReceiver(Device); impl Notifier for PipeReceiver { type Event = u32; fn poll_next(mut self: Pin<&mut Self>, task: &mut Task<'_>) -> Poll { - let device = self.0.as_mut().unwrap(); + let device = &mut self.0; if Pin::new(&mut *device).poll_next(task).is_pending() { return Pending; @@ -35,8 +37,11 @@ impl Notifier for PipeReceiver { unsafe { let mut x = MaybeUninit::::uninit(); - if read(device.fd(), x.as_mut_ptr().cast(), mem::size_of::()) - == mem::size_of::().try_into().unwrap() + if read( + device.fd().as_raw_fd(), + x.as_mut_ptr().cast(), + mem::size_of::(), + ) == mem::size_of::().try_into().unwrap() { Ready(x.assume_init()) } else { @@ -46,54 +51,40 @@ impl Notifier for PipeReceiver { } } -impl Drop for PipeReceiver { - fn drop(&mut self) { - // Remove from watchlist - let device = self.0.take().unwrap(); - let fd = device.fd(); - drop(device); - // Close file descriptor - let ret = unsafe { close(fd) }; - assert_eq!(0, ret); - } -} - /// A `PipeSender` device. -pub struct PipeSender(RawFd); +pub struct PipeSender(OwnedFd); impl PipeSender { /// Send a 32-bit value over the pipe. pub fn send(&self, value: u32) { let data = [value]; let len: usize = unsafe { - write(self.0, data.as_ptr().cast(), mem::size_of::()) - .try_into() - .unwrap() + write( + self.0.as_raw_fd(), + data.as_ptr().cast(), + mem::size_of::(), + ) + .try_into() + .unwrap() }; assert_eq!(len, mem::size_of::()); } } -impl Drop for PipeSender { - fn drop(&mut self) { - unsafe { - let ret = close(self.0); - assert_eq!(0, ret); - } - } -} - /// Create a new `Pipe`. pub fn pipe() -> (PipeReceiver, PipeSender) { - let [fd, sender] = unsafe { + let (fd, sender) = unsafe { // Create pipe for communication let mut pipe = mem::MaybeUninit::<[raw::c_int; 2]>::uninit(); let ret = pipe2(pipe.as_mut_ptr(), O_CLOEXEC | O_NONBLOCK | O_DIRECT); assert!(ret >= 0); - pipe.assume_init() + let [fd, sender] = pipe.assume_init(); + assert_ne!(fd, -1); + assert_ne!(sender, -1); + (OwnedFd::from_raw_fd(fd), OwnedFd::from_raw_fd(sender)) }; - let device = Some(Device::builder().input().watch(fd)); + let device = Device::builder().input().watch(fd); (PipeReceiver(device), PipeSender(sender)) } diff --git a/examples/sleep.rs b/examples/sleep.rs index 73dba31..c4adaf2 100644 --- a/examples/sleep.rs +++ b/examples/sleep.rs @@ -1,7 +1,10 @@ use std::{ convert::TryInto, mem::{self, MaybeUninit}, - os::{raw, unix::io::RawFd}, + os::{ + fd::{AsRawFd, FromRawFd, OwnedFd, RawFd}, + raw, + }, ptr, time::Duration, }; @@ -31,23 +34,10 @@ extern "C" { old_value: *mut ITimerSpec, ) -> raw::c_int; fn read(fd: RawFd, buf: *mut u64, count: usize) -> isize; - fn close(fd: RawFd) -> raw::c_int; } /// A `Timer` device future. -pub struct Timer(Option); - -impl Drop for Timer { - fn drop(&mut self) { - // Remove from watchlist - let device = self.0.take().unwrap(); - let fd = device.fd(); - drop(device); - // Close file descriptor - let ret = unsafe { close(fd) }; - assert_eq!(0, ret); - } -} +pub struct Timer(Device); impl Timer { /// Create a new `Timer`. @@ -62,7 +52,9 @@ impl Timer { }; let _ret = unsafe { timerfd_settime(fd, 0, &its, ptr::null_mut()) }; assert_eq!(0, _ret); - Self(Some(Device::builder().input().watch(fd))) + assert_ne!(fd, -1); + let fd = unsafe { OwnedFd::from_raw_fd(fd) }; + Self(Device::builder().input().watch(fd)) } } @@ -70,7 +62,7 @@ impl Notifier for Timer { type Event = usize; fn poll_next(mut self: Pin<&mut Self>, task: &mut Task<'_>) -> Poll { - let device = self.0.as_mut().unwrap(); + let device = &mut self.0; if Pin::new(&mut *device).poll_next(task).is_pending() { return Pending; @@ -78,8 +70,11 @@ impl Notifier for Timer { unsafe { let mut x = MaybeUninit::::uninit(); - if read(device.fd(), x.as_mut_ptr(), mem::size_of::()) - == mem::size_of::().try_into().unwrap() + if read( + device.fd().as_raw_fd(), + x.as_mut_ptr(), + mem::size_of::(), + ) == mem::size_of::().try_into().unwrap() { let count = x.assume_init().try_into().unwrap(); if count == 0 { diff --git a/src/epoll.rs b/src/epoll.rs index 4153989..7855847 100644 --- a/src/epoll.rs +++ b/src/epoll.rs @@ -1,4 +1,4 @@ -// Copyright © 2020-2022 The Smelling Salts Contributors. +// Copyright © 2020-2023 The Smelling Salts Contributors. // // Licensed under any of: // - Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0) @@ -15,8 +15,8 @@ use std::{ mem::{self, MaybeUninit}, os::{ + fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}, raw::{c_int, c_void}, - unix::io::RawFd, }, sync::{Arc, Once}, }; @@ -24,8 +24,6 @@ use std::{ use pasts::prelude::*; use whisk::{Channel, Queue}; -type Poll = pasts::prelude::Poll; - const EPOLLIN: u32 = 0x0001; const EPOLLOUT: u32 = 0x0004; const EPOLLET: u32 = 1 << 31; @@ -36,7 +34,7 @@ const EPOLLET: u32 = 1 << 31; #[derive(Debug)] pub struct Device { channel: Channel, - fd: RawFd, + owned_fd: OwnedFd, } impl Device { @@ -46,8 +44,8 @@ impl Device { } /// Get the file descriptor for this device - pub fn fd(&self) -> RawFd { - self.fd + pub fn fd(&self) -> BorrowedFd<'_> { + self.owned_fd.as_fd() } } @@ -63,7 +61,9 @@ impl Drop for Device { fn drop(&mut self) { let epoll_fd = state().epoll_fd; let mut _ev = MaybeUninit::::zeroed(); - let ret = unsafe { epoll_ctl(epoll_fd, 2, self.fd, _ev.as_mut_ptr()) }; + let ret = unsafe { + epoll_ctl(epoll_fd, 2, self.fd().as_raw_fd(), _ev.as_mut_ptr()) + }; assert_eq!(ret, 0); } } @@ -93,7 +93,8 @@ impl DeviceBuilder { } /// Finish building the [`Device`] - pub fn watch(self, fd: RawFd) -> Device { + pub fn watch(self, fd: impl Into) -> Device { + let owned_fd = fd.into(); let state = state(); let channel = Channel::new(); let queue: Arc = channel.clone().into(); @@ -101,10 +102,12 @@ impl DeviceBuilder { let data = EpollData { ptr }; let events = self.events; let mut event = EpollEvent { events, data }; - let ret = unsafe { epoll_ctl(state.epoll_fd, 1, fd, &mut event) }; + let ret = unsafe { + epoll_ctl(state.epoll_fd, 1, owned_fd.as_raw_fd(), &mut event) + }; assert_eq!(ret, 0); - Device { channel, fd } + Device { channel, owned_fd } } } diff --git a/src/lib.rs b/src/lib.rs index b819371..787ee7d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright © 2020-2022 The Smelling Salts Contributors. +// Copyright © 2020-2023 The Smelling Salts Contributors. // // Licensed under any of: // - Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)