From 52c049fe14ec725ec70761cf640acff6262c56d7 Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Sun, 9 Feb 2025 18:21:53 -0500 Subject: [PATCH] For recvmmsg split lifetime 'a into separate lifetimes for 'data, headers ('hdr) and related iterator --- src/sys/socket/mod.rs | 23 +++++++++++++---------- test/sys/test_socket.rs | 40 +++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 78a759fb90..966840cb51 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1765,7 +1765,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>( // shared across all the messages cmsgs: C, flags: MsgFlags -) -> crate::Result> +) -> crate::Result> where XS: IntoIterator, AS: AsRef<[Option]>, @@ -1820,6 +1820,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>( Ok(MultiResults { rmm: data, current_index: 0, + slices: std::marker::PhantomData, received: sent }) @@ -1908,16 +1909,16 @@ impl MultiHeaders { // always produce the desired results - see https://github.com/nix-rust/nix/pull/1744 for more // details #[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] -pub fn recvmmsg<'a, XS, S, I>( +pub fn recvmmsg<'hdr, 'iter, 'data, XS, S, I>( fd: RawFd, - data: &'a mut MultiHeaders, + data: &'hdr mut MultiHeaders, slices: XS, flags: MsgFlags, mut timeout: Option, -) -> crate::Result> +) -> crate::Result> where - XS: IntoIterator, - I: AsMut<[IoSliceMut<'a>]> + 'a, + XS: IntoIterator, + I: AsMut<[IoSliceMut<'data>]> + 'iter, { let mut count = 0; for (i, (slice, mmsghdr)) in slices.into_iter().zip(data.items.iter_mut()).enumerate() { @@ -1949,6 +1950,7 @@ where })? as usize; Ok(MultiResults { + slices: std::marker::PhantomData, rmm: data, current_index: 0, received, @@ -1958,19 +1960,20 @@ where /// Iterator over results of [`recvmmsg`]/[`sendmmsg`] #[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] #[derive(Debug)] -pub struct MultiResults<'a, S> { +pub struct MultiResults<'hdrs, 'data, S> { // preallocated structures - rmm: &'a MultiHeaders, + rmm: &'hdrs MultiHeaders, + slices: std::marker::PhantomData<&'data ()>, current_index: usize, received: usize, } #[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))] -impl<'a, S> Iterator for MultiResults<'a, S> +impl<'hdrs, 'data, S> Iterator for MultiResults<'hdrs, 'data, S> where S: Copy + SockaddrLike, { - type Item = RecvMsg<'a, 'a, S>; + type Item = RecvMsg<'hdrs, 'data, S>; // The cast is not unnecessary on all platforms. #[allow(clippy::unnecessary_cast)] diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs index 5a43aab437..1605f81757 100644 --- a/test/sys/test_socket.rs +++ b/test/sys/test_socket.rs @@ -646,8 +646,9 @@ mod recvfrom { ) .expect("send socket failed"); + const LOOPS: usize = 3; let send_thread = thread::spawn(move || { - for _ in 0..NUM_MESSAGES_SENT { + for _ in 0..NUM_MESSAGES_SENT * LOOPS { sendto( ssock.as_raw_fd(), &DATA[..], @@ -671,24 +672,29 @@ mod recvfrom { let mut data = MultiHeaders::::preallocate(msgs.len(), None); - let res: Vec> = recvmmsg( - rsock.as_raw_fd(), - &mut data, - msgs.iter_mut(), - MsgFlags::empty(), - None, - ) - .expect("recvmmsg") - .collect(); - assert_eq!(res.len(), DATA.len()); + for _ in 0..LOOPS { + let res: Vec> = recvmmsg( + rsock.as_raw_fd(), + &mut data, + msgs.iter_mut(), + MsgFlags::empty(), + None, + ) + .expect("recvmmsg") + .collect(); + assert_eq!(res.len(), DATA.len()); - for RecvMsg { address, bytes, .. } in res.into_iter() { - assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap()); - assert_eq!(DATA.len(), bytes); - } + for RecvMsg { address, bytes, .. } in res.into_iter() { + assert_eq!( + AddressFamily::Inet, + address.unwrap().family().unwrap() + ); + assert_eq!(DATA.len(), bytes); + } - for buf in &receive_buffers { - assert_eq!(&buf[..DATA.len()], DATA); + for buf in msgs.iter().flatten() { + assert_eq!(&buf[..DATA.len()], DATA); + } } send_thread.join().unwrap();