| //! Solaris/illumos event ports. |
| |
| use crate::backend::c; |
| use crate::backend::io::syscalls; |
| use crate::fd::{AsFd, AsRawFd, OwnedFd}; |
| use crate::io; |
| |
| use super::PollFlags; |
| |
| use core::convert::TryInto; |
| use core::time::Duration; |
| |
| /// The structure representing a port event. |
| #[repr(transparent)] |
| pub struct Event(pub(crate) c::port_event); |
| |
| impl Event { |
| /// Get the events associated with this event. |
| pub fn events(&self) -> i32 { |
| self.0.portev_events |
| } |
| |
| /// Get the event source associated with this event. |
| pub fn object(&self) -> usize { |
| self.0.portev_object |
| } |
| |
| /// Get the userdata associated with this event. |
| pub fn userdata(&self) -> *mut c::c_void { |
| self.0.portev_user |
| } |
| } |
| |
| /// `port_create()`—Creates a new port. |
| /// |
| /// # References |
| /// - [OpenSolaris] |
| /// - [illumos] |
| /// |
| /// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_create/ |
| /// [illumos]: https://illumos.org/man/3C/port_create |
| pub fn port_create() -> io::Result<OwnedFd> { |
| syscalls::port_create() |
| } |
| |
| /// `port_associate(_, PORT_SOURCE_FD, _, _, _)`—Associates a file descriptor |
| /// with a port. |
| /// |
| /// # Safety |
| /// |
| /// Any `object`s passed into the `port` must be valid for the lifetime of the |
| /// `port`. Logically, `port` keeps a borrowed reference to the `object` until |
| /// it is removed via `port_dissociate_fd`. |
| /// |
| /// # References |
| /// - [OpenSolaris] |
| /// - [illumos] |
| /// |
| /// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_associate/ |
| /// [illumos]: https://illumos.org/man/3C/port_associate |
| pub unsafe fn port_associate_fd( |
| port: impl AsFd, |
| object: impl AsRawFd, |
| events: PollFlags, |
| userdata: *mut c::c_void, |
| ) -> io::Result<()> { |
| syscalls::port_associate( |
| port.as_fd(), |
| c::PORT_SOURCE_FD, |
| object.as_raw_fd() as _, |
| events.bits() as _, |
| userdata.cast(), |
| ) |
| } |
| |
| /// `port_dissociate(_, PORT_SOURCE_FD, _)`—Dissociates a file descriptor from |
| /// a port. |
| /// |
| /// # Safety |
| /// |
| /// The file descriptor passed into this function must have been previously |
| /// associated with the port via [`port_associate_fd`]. |
| /// |
| /// # References |
| /// - [OpenSolaris] |
| /// - [illumos] |
| /// |
| /// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_dissociate |
| /// [illumos]: https://illumos.org/man/3C/port_dissociate |
| pub unsafe fn port_dissociate_fd(port: impl AsFd, object: impl AsRawFd) -> io::Result<()> { |
| syscalls::port_dissociate(port.as_fd(), c::PORT_SOURCE_FD, object.as_raw_fd() as _) |
| } |
| |
| /// `port_get(port, timeout)`—Gets an event from a port. |
| /// |
| /// # References |
| /// - [OpenSolaris] |
| /// - [illumos] |
| /// |
| /// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_get/ |
| /// [illumos]: https://illumos.org/man/3C/port_get |
| pub fn port_get(port: impl AsFd, timeout: Option<Duration>) -> io::Result<Event> { |
| let mut timeout = timeout.map(|timeout| c::timespec { |
| tv_sec: timeout.as_secs().try_into().unwrap(), |
| tv_nsec: timeout.subsec_nanos() as _, |
| }); |
| |
| syscalls::port_get(port.as_fd(), timeout.as_mut()) |
| } |
| |
| /// `port_getn(port, events, min_events, timeout)`—Gets multiple events from a |
| /// port. |
| /// |
| /// # References |
| /// - [OpenSolaris] |
| /// - [illumos] |
| /// |
| /// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_getn/ |
| /// [illumos]: https://illumos.org/man/3C/port_getn |
| pub fn port_getn( |
| port: impl AsFd, |
| events: &mut Vec<Event>, |
| min_events: usize, |
| timeout: Option<Duration>, |
| ) -> io::Result<()> { |
| events.clear(); |
| |
| let mut timeout = timeout.map(|timeout| c::timespec { |
| tv_sec: timeout.as_secs().try_into().unwrap(), |
| tv_nsec: timeout.subsec_nanos() as _, |
| }); |
| |
| syscalls::port_getn( |
| port.as_fd(), |
| timeout.as_mut(), |
| events, |
| min_events.try_into().unwrap(), |
| ) |
| } |
| |
| /// `port_send(port, events, userdata)`—Sends an event to a port. |
| /// |
| /// # References |
| /// - [OpenSolaris] |
| /// - [illumos] |
| /// |
| /// [OpenSolaris]: https://www.unix.com/man-page/opensolaris/3C/port_send/ |
| /// [illumos]: https://illumos.org/man/3C/port_send |
| pub fn port_send(port: impl AsFd, events: i32, userdata: *mut c::c_void) -> io::Result<()> { |
| syscalls::port_send(port.as_fd(), events, userdata.cast()) |
| } |