Skip to content

Commit f63e6ce

Browse files
committed
For recvmmsg split lifetime 'a
into separate lifetimes for 'data, headers ('hdr) and related iterator
1 parent 1b0dba6 commit f63e6ce

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

src/sys/socket/mod.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use libc::{
1717
};
1818
#[cfg(not(target_os = "redox"))]
1919
use std::io::{IoSlice, IoSliceMut};
20+
use std::marker::PhantomData;
2021
#[cfg(feature = "net")]
2122
use std::net;
2223
use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd};
@@ -1765,7 +1766,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
17651766
// shared across all the messages
17661767
cmsgs: C,
17671768
flags: MsgFlags
1768-
) -> crate::Result<MultiResults<'a, S>>
1769+
) -> crate::Result<MultiResults<'a, 'a, S>>
17691770
where
17701771
XS: IntoIterator<Item = &'a I>,
17711772
AS: AsRef<[Option<S>]>,
@@ -1820,6 +1821,7 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
18201821
Ok(MultiResults {
18211822
rmm: data,
18221823
current_index: 0,
1824+
slices: PhantomData,
18231825
received: sent
18241826
})
18251827

@@ -1908,16 +1910,16 @@ impl<S> MultiHeaders<S> {
19081910
// always produce the desired results - see https://github.com/nix-rust/nix/pull/1744 for more
19091911
// details
19101912
#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
1911-
pub fn recvmmsg<'a, XS, S, I>(
1913+
pub fn recvmmsg<'hdr, 'iter, 'data, XS, S, I>(
19121914
fd: RawFd,
1913-
data: &'a mut MultiHeaders<S>,
1915+
data: &'hdr mut MultiHeaders<S>,
19141916
slices: XS,
19151917
flags: MsgFlags,
19161918
mut timeout: Option<crate::sys::time::TimeSpec>,
1917-
) -> crate::Result<MultiResults<'a, S>>
1919+
) -> crate::Result<MultiResults<'hdr, 'data, S>>
19181920
where
1919-
XS: IntoIterator<Item = &'a mut I>,
1920-
I: AsMut<[IoSliceMut<'a>]> + 'a,
1921+
XS: IntoIterator<Item = &'iter mut I>,
1922+
I: AsMut<[IoSliceMut<'data>]> + 'iter,
19211923
{
19221924
let mut count = 0;
19231925
for (i, (slice, mmsghdr)) in slices.into_iter().zip(data.items.iter_mut()).enumerate() {
@@ -1949,6 +1951,7 @@ where
19491951
})? as usize;
19501952

19511953
Ok(MultiResults {
1954+
slices: PhantomData,
19521955
rmm: data,
19531956
current_index: 0,
19541957
received,
@@ -1958,19 +1961,20 @@ where
19581961
/// Iterator over results of [`recvmmsg`]/[`sendmmsg`]
19591962
#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
19601963
#[derive(Debug)]
1961-
pub struct MultiResults<'a, S> {
1964+
pub struct MultiResults<'hdrs, 'data, S> {
19621965
// preallocated structures
1963-
rmm: &'a MultiHeaders<S>,
1966+
rmm: &'hdrs MultiHeaders<S>,
1967+
slices: PhantomData<&'data ()>,
19641968
current_index: usize,
19651969
received: usize,
19661970
}
19671971

19681972
#[cfg(any(linux_android, target_os = "freebsd", target_os = "netbsd"))]
1969-
impl<'a, S> Iterator for MultiResults<'a, S>
1973+
impl<'hdrs, 'data, S> Iterator for MultiResults<'hdrs, 'data, S>
19701974
where
19711975
S: Copy + SockaddrLike,
19721976
{
1973-
type Item = RecvMsg<'a, 'a, S>;
1977+
type Item = RecvMsg<'hdrs, 'data, S>;
19741978

19751979
// The cast is not unnecessary on all platforms.
19761980
#[allow(clippy::unnecessary_cast)]

test/sys/test_socket.rs

+21-16
Original file line numberDiff line numberDiff line change
@@ -671,24 +671,29 @@ mod recvfrom {
671671
let mut data =
672672
MultiHeaders::<SockaddrIn>::preallocate(msgs.len(), None);
673673

674-
let res: Vec<RecvMsg<SockaddrIn>> = recvmmsg(
675-
rsock.as_raw_fd(),
676-
&mut data,
677-
msgs.iter_mut(),
678-
MsgFlags::empty(),
679-
None,
680-
)
681-
.expect("recvmmsg")
682-
.collect();
683-
assert_eq!(res.len(), DATA.len());
674+
for _ in 0..3 {
675+
let res: Vec<RecvMsg<SockaddrIn>> = recvmmsg(
676+
rsock.as_raw_fd(),
677+
&mut data,
678+
msgs.iter_mut(),
679+
MsgFlags::empty(),
680+
None,
681+
)
682+
.expect("recvmmsg")
683+
.collect();
684+
assert_eq!(res.len(), DATA.len());
684685

685-
for RecvMsg { address, bytes, .. } in res.into_iter() {
686-
assert_eq!(AddressFamily::Inet, address.unwrap().family().unwrap());
687-
assert_eq!(DATA.len(), bytes);
688-
}
686+
for RecvMsg { address, bytes, .. } in res.into_iter() {
687+
assert_eq!(
688+
AddressFamily::Inet,
689+
address.unwrap().family().unwrap()
690+
);
691+
assert_eq!(DATA.len(), bytes);
692+
}
689693

690-
for buf in &receive_buffers {
691-
assert_eq!(&buf[..DATA.len()], DATA);
694+
for buf in msgs.iter().flatten() {
695+
assert_eq!(&buf[..DATA.len()], DATA);
696+
}
692697
}
693698

694699
send_thread.join().unwrap();

0 commit comments

Comments
 (0)