Skip to content

Commit cc22957

Browse files
committed
Support creating an Async with AsFd rather than AsRawFd
Add a `new_with_asfd` constructor that works just like `new` but uses `AsFd` rather than `AsRawFd`. This makes use of the newly factored out `set_nonblocking` helper, with which the body of the new constructor is just a few lines.
1 parent 002423e commit cc22957

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

src/lib.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,42 @@ fn set_nonblocking(fd: BorrowedFd<'_>) -> io::Result<()> {
647647
Ok(())
648648
}
649649

650+
#[cfg(unix)]
651+
impl<T: AsFd> Async<T> {
652+
/// Creates an async I/O handle.
653+
///
654+
/// This method will put the handle in non-blocking mode and register it in
655+
/// [epoll]/[kqueue]/[event ports]/[IOCP].
656+
///
657+
/// On Unix systems, the handle must implement `AsFd`, while on Windows it must implement
658+
/// `AsSocket`.
659+
///
660+
/// [epoll]: https://en.wikipedia.org/wiki/Epoll
661+
/// [kqueue]: https://en.wikipedia.org/wiki/Kqueue
662+
/// [event ports]: https://illumos.org/man/port_create
663+
/// [IOCP]: https://learn.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports
664+
///
665+
/// # Examples
666+
///
667+
/// ```
668+
/// use async_io::Async;
669+
/// use std::net::{SocketAddr, TcpListener};
670+
///
671+
/// # futures_lite::future::block_on(async {
672+
/// let listener = TcpListener::bind(SocketAddr::from(([127, 0, 0, 1], 0)))?;
673+
/// let listener = Async::new(listener)?;
674+
/// # std::io::Result::Ok(()) });
675+
/// ```
676+
pub fn new_with_asfd(io: T) -> io::Result<Async<T>> {
677+
let fd = io.as_fd();
678+
set_nonblocking(fd)?;
679+
Ok(Async {
680+
source: Reactor::get().insert_io(fd.as_raw_fd())?,
681+
io: Some(io),
682+
})
683+
}
684+
}
685+
650686
#[cfg(unix)]
651687
impl<T: AsRawFd> Async<T> {
652688
/// Creates an async I/O handle.
@@ -719,6 +755,42 @@ impl<T: Into<OwnedFd>> TryFrom<Async<T>> for OwnedFd {
719755
}
720756
}
721757

758+
#[cfg(windows)]
759+
impl<T: AsSocket> Async<T> {
760+
/// Creates an async I/O handle.
761+
///
762+
/// This method will put the handle in non-blocking mode and register it in
763+
/// [epoll]/[kqueue]/[event ports]/[IOCP].
764+
///
765+
/// On Unix systems, the handle must implement `AsFd`, while on Windows it must implement
766+
/// `AsSocket`.
767+
///
768+
/// [epoll]: https://en.wikipedia.org/wiki/Epoll
769+
/// [kqueue]: https://en.wikipedia.org/wiki/Kqueue
770+
/// [event ports]: https://illumos.org/man/port_create
771+
/// [IOCP]: https://learn.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports
772+
///
773+
/// # Examples
774+
///
775+
/// ```
776+
/// use async_io::Async;
777+
/// use std::net::{SocketAddr, TcpListener};
778+
///
779+
/// # futures_lite::future::block_on(async {
780+
/// let listener = TcpListener::bind(SocketAddr::from(([127, 0, 0, 1], 0)))?;
781+
/// let listener = Async::new(listener)?;
782+
/// # std::io::Result::Ok(()) });
783+
/// ```
784+
pub fn new_with_asfd(io: T) -> io::Result<Async<T>> {
785+
let borrowed = io.as_socket();
786+
set_nonblocking(borrowed)?;
787+
Ok(Async {
788+
source: Reactor::get().insert_io(borrowed.as_raw_socket())?,
789+
io: Some(io),
790+
})
791+
}
792+
}
793+
722794
#[cfg(windows)]
723795
impl<T: AsRawSocket> Async<T> {
724796
/// Creates an async I/O handle.

0 commit comments

Comments
 (0)