From e381953f2136686dfd8d30665324680107fd248f Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sat, 30 Dec 2023 19:23:33 +0100 Subject: [PATCH] Add UnixDatagram::from_std Convertion std lib -> Heph. --- rt/src/net/uds/datagram.rs | 19 ++++++++++++++++++ rt/tests/functional/uds/datagram.rs | 31 ++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/rt/src/net/uds/datagram.rs b/rt/src/net/uds/datagram.rs index 52335ac2b..ab146d468 100644 --- a/rt/src/net/uds/datagram.rs +++ b/rt/src/net/uds/datagram.rs @@ -126,6 +126,25 @@ impl UnixDatagram { }) } + /// Converts a [`std::os::unix::net::UnixDatagram`] to a + /// [`heph_rt::net::UnixDatagram`]. + /// + /// [`heph_rt::net::UnixDatagram`]: UnixDatagram + /// + /// # Notes + /// + /// It's up to the caller to ensure that the socket's mode is correctly set + /// to [`Connected`] or [`Unconnected`]. + pub fn from_std(rt: &RT, socket: std::os::unix::net::UnixDatagram) -> UnixDatagram + where + RT: Access, + { + UnixDatagram { + fd: AsyncFd::new(socket.into(), rt.submission_queue()), + mode: PhantomData, + } + } + /// Returns the socket address of the remote peer of this socket. pub fn peer_addr(&self) -> io::Result { self.with_ref(|socket| socket.peer_addr().map(|a| UnixAddr { inner: a })) diff --git a/rt/tests/functional/uds/datagram.rs b/rt/tests/functional/uds/datagram.rs index 49f847324..b817c01d8 100644 --- a/rt/tests/functional/uds/datagram.rs +++ b/rt/tests/functional/uds/datagram.rs @@ -6,8 +6,10 @@ use std::time::Duration; use heph::actor::{self, actor_fn}; use heph_rt::net::uds::{UnixAddr, UnixDatagram}; +use heph_rt::net::Unconnected; use heph_rt::spawn::ActorOptions; -use heph_rt::test::{join, try_spawn_local, PanicSupervisor}; +use heph_rt::test::{block_on_local_actor, join, try_spawn_local, PanicSupervisor}; +use heph_rt::ThreadLocal; use heph_rt::{self as rt}; use crate::util::temp_file; @@ -101,3 +103,30 @@ fn bound() { let actor_ref = try_spawn_local(PanicSupervisor, actor, (), ActorOptions::default()).unwrap(); join(&actor_ref, Duration::from_secs(1)).unwrap(); } + +#[test] +fn socket_from_std() { + async fn actor(ctx: actor::Context) -> io::Result<()> { + let path1 = temp_file("uds.socket_from_std1"); + let path2 = temp_file("uds.socket_from_std2"); + let socket = std::os::unix::net::UnixDatagram::bind(path1)?; + let socket = UnixDatagram::::from_std(ctx.runtime_ref(), socket); + let local_address = socket.local_addr()?; + + let peer = std::os::unix::net::UnixDatagram::bind(path2)?; + let peer_address = UnixAddr::from_pathname(peer.local_addr()?.as_pathname().unwrap())?; + + let (_, bytes_written) = socket.send_to(DATA, peer_address).await?; + assert_eq!(bytes_written, DATA.len()); + + let mut buf = vec![0; DATA.len() + 2]; + let (n, address) = peer.recv_from(&mut buf)?; + assert_eq!(n, DATA.len()); + assert_eq!(&buf[..n], DATA); + assert_eq!(address.as_pathname(), local_address.as_pathname()); + + Ok(()) + } + + block_on_local_actor(actor_fn(actor), ()).unwrap(); +}