Skip to content

Commit

Permalink
Add a port_getn_query function. (#1216)
Browse files Browse the repository at this point in the history
* Add a `port_getn_query` function.

The solarish [`port_getn` function] special-cases a `max` argument value
of 0 to be a query of the number of events available. #1215 added a
special-case to protect the code from doing a resize in that case. And
in case users actually do want to do a query, this PR adds a new
`port_getn_query` function that passes a zero.

[`port_getn` function]: https://illumos.org/man/3C/port_getn

* Fix errors.

* Update src/event/port.rs

Co-authored-by: 王宇逸 <[email protected]>

---------

Co-authored-by: 王宇逸 <[email protected]>
  • Loading branch information
sunfishcode and Berrysoft committed Nov 18, 2024
1 parent 92bb625 commit 10f85a8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/backend/libc/event/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,13 @@ pub(crate) fn port_getn(
events: &mut Vec<Event>,
mut nget: u32,
) -> io::Result<()> {
// `port_getn` special-cases a max value of 0 to be a query that returns
// the number of events. We don't want to do the `set_len` in that case, so
// so bail out early if needed.
if events.capacity() == 0 {
return Ok(());
}

let timeout = timeout.map_or(null_mut(), as_mut_ptr);
unsafe {
ret(c::port_getn(
Expand All @@ -336,6 +340,24 @@ pub(crate) fn port_getn(
Ok(())
}

#[cfg(solarish)]
pub(crate) fn port_getn_query(port: BorrowedFd<'_>) -> io::Result<u32> {
let mut nget: u32 = 0;

// Pass a `max` of 0 to query the number of available events.
unsafe {
ret(c::port_getn(
borrowed_fd(port),
null_mut(),
0,
&mut nget,
null_mut(),
))?;
}

Ok(nget)
}

#[cfg(solarish)]
pub(crate) fn port_send(
port: BorrowedFd<'_>,
Expand Down
22 changes: 22 additions & 0 deletions src/event/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ pub fn port_get(port: impl AsFd, timeout: Option<Duration>) -> io::Result<Event>
/// `port_getn(port, events, min_events, timeout)`—Gets multiple events from a
/// port.
///
/// This requests up to a max of `events.capacity()` events, and then resizes
/// `events` to the number of events retrieved. If `events.capacity()` is 0,
/// this does nothing and returns immediately.
///
/// To query the number of events without retrieving any, use
/// [`port_getn_query`].
///
/// # References
/// - [OpenSolaris]
/// - [illumos]
Expand Down Expand Up @@ -138,6 +145,21 @@ pub fn port_getn(
)
}

/// `port_getn(port, NULL, 0, NULL)`—Queries the number of events
/// available from a port.
///
/// To retrieve the events, use [`port_getn`].
///
/// # 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_query(port: impl AsFd) -> io::Result<u32> {
syscalls::port_getn_query(port.as_fd())
}

/// `port_send(port, events, userdata)`—Sends an event to a port.
///
/// # References
Expand Down

0 comments on commit 10f85a8

Please sign in to comment.