Skip to content

Commit b5350c7

Browse files
committed
Add test
1 parent cc1ba57 commit b5350c7

File tree

2 files changed

+88
-92
lines changed

2 files changed

+88
-92
lines changed

src/lib.rs

Lines changed: 66 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ macro_rules! define_mmsg_if_supported {
176176
($($item:item)*) => {
177177
$(
178178
#[cfg(all(
179-
feature = "all",
180179
any(
181180
target_os = "linux",
182181
target_os = "android",
@@ -714,105 +713,87 @@ impl<'name, 'bufs, 'control> fmt::Debug for MsgHdrMut<'name, 'bufs, 'control> {
714713
}
715714

716715
define_mmsg_if_supported! {
717-
/// Wraps `mmsghdr` on Unix for a `sendmmsg(2)` system call.
718-
///
719-
/// Also see [`MsgHdr`] for the variant used by `sendmsg(2)`.
720-
#[repr(transparent)]
721-
pub struct MMsgHdr<'addr, 'bufs, 'control> {
722-
inner: sys::mmsghdr,
723-
#[allow(clippy::type_complexity)]
724-
_lifetimes: PhantomData<(&'addr SockAddr, &'bufs IoSlice<'bufs>, &'control [u8])>,
725-
}
726-
727-
impl<'addr, 'bufs, 'control> MMsgHdr<'addr, 'bufs, 'control> {
728-
/// Create a new `MMsgHdr` from `MsgHdr` and with the `msg_len` set to zero.
729-
pub fn new(msg: MsgHdr<'_, '_, '_>) -> Self {
730-
Self {
731-
inner: sys::mmsghdr {
732-
msg_hdr: msg.inner,
733-
msg_len: 0,
734-
},
735-
_lifetimes: PhantomData,
736-
}
737-
}
716+
/// Wraps `mmsghdr` on Unix for a `sendmmsg(2)` system call.
717+
///
718+
/// Also see [`MsgHdr`] for the variant used by `sendmsg(2)`.
719+
#[repr(transparent)]
720+
pub struct MMsgHdr<'addr, 'bufs, 'control> {
721+
inner: sys::mmsghdr,
722+
#[allow(clippy::type_complexity)]
723+
_lifetimes: PhantomData<(&'addr SockAddr, &'bufs IoSlice<'bufs>, &'control [u8])>,
724+
}
738725

739-
/// Number of bytes transmitted.
740-
pub fn transmitted_bytes(&self) -> u32 {
741-
self.inner.msg_len
726+
impl<'addr, 'bufs, 'control> MMsgHdr<'addr, 'bufs, 'control> {
727+
/// Create a new `MMsgHdr` from `MsgHdr` and with the `msg_len` set to zero.
728+
pub fn new(msg: MsgHdr<'_, '_, '_>) -> Self {
729+
Self {
730+
inner: sys::mmsghdr {
731+
msg_hdr: msg.inner,
732+
msg_len: 0,
733+
},
734+
_lifetimes: PhantomData,
742735
}
743736
}
744737

745-
impl<'addr, 'bufs, 'control> From<MsgHdr<'addr, 'bufs, 'control>>
746-
for MMsgHdr<'addr, 'bufs, 'control>
747-
{
748-
fn from(value: MsgHdr<'_, '_, '_>) -> Self {
749-
Self::new(value)
750-
}
738+
/// Number of bytes transmitted.
739+
pub fn transmitted_bytes(&self) -> u32 {
740+
self.inner.msg_len
751741
}
742+
}
752743

753-
impl<'addr, 'bufs, 'control> fmt::Debug for MMsgHdr<'addr, 'bufs, 'control> {
754-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
755-
f.write_str("MMsgHdr({})", self.len())
756-
}
744+
impl<'addr, 'bufs, 'control> fmt::Debug for MMsgHdr<'addr, 'bufs, 'control> {
745+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
746+
f.write_str(&format!("MMsgHdr({})", self.transmitted_bytes()))
757747
}
748+
}
758749

759-
/// Wraps `mmsghdr` on Unix for a `recvmmsg(2)` system call.
760-
///
761-
/// Also see [`MsgHdrMut`] for the variant used by `recvmsg(2)`.
762-
#[repr(transparent)]
763-
pub struct MMsgHdrMut<'addr, 'bufs, 'control> {
764-
inner: sys::mmsghdr,
765-
#[allow(clippy::type_complexity)]
766-
_lifetimes: PhantomData<(
767-
&'addr mut SockAddr,
768-
&'bufs mut MaybeUninitSlice<'bufs>,
769-
&'control mut [u8],
770-
)>,
771-
}
772-
773-
impl<'addr, 'bufs, 'control> MMsgHdrMut<'addr, 'bufs, 'control> {
774-
/// Create a new `MMsgHdrMut` from `MsgHdrMut` and with the `msg_len` set to zero.
775-
pub fn new(msg: MsgHdrMut<'_, '_, '_>) -> Self {
776-
Self {
777-
inner: sys::mmsghdr {
778-
msg_hdr: msg.inner,
779-
msg_len: 0,
780-
},
781-
_lifetimes: PhantomData,
782-
}
783-
}
750+
/// Wraps `mmsghdr` on Unix for a `recvmmsg(2)` system call.
751+
///
752+
/// Also see [`MsgHdrMut`] for the variant used by `recvmsg(2)`.
753+
#[repr(transparent)]
754+
pub struct MMsgHdrMut<'addr, 'bufs, 'control> {
755+
inner: sys::mmsghdr,
756+
#[allow(clippy::type_complexity)]
757+
_lifetimes: PhantomData<(
758+
&'addr mut SockAddr,
759+
&'bufs mut MaybeUninitSlice<'bufs>,
760+
&'control mut [u8],
761+
)>,
762+
}
784763

785-
/// Number of received bytes.
786-
pub fn transmitted_bytes(&self) -> u32 {
787-
self.inner.msg_len
764+
impl<'addr, 'bufs, 'control> MMsgHdrMut<'addr, 'bufs, 'control> {
765+
/// Create a new `MMsgHdrMut` from `MsgHdrMut` and with the `msg_len` set to zero.
766+
pub fn new(msg: MsgHdrMut<'_, '_, '_>) -> Self {
767+
Self {
768+
inner: sys::mmsghdr {
769+
msg_hdr: msg.inner,
770+
msg_len: 0,
771+
},
772+
_lifetimes: PhantomData,
788773
}
774+
}
789775

790-
/// Returns the flags of the message.
791-
pub fn flags(&self) -> RecvFlags {
792-
sys::msghdr_flags(&self.inner.msg_hdr)
793-
}
776+
/// Number of received bytes.
777+
pub fn recieved_bytes(&self) -> u32 {
778+
self.inner.msg_len
779+
}
794780

795-
/// Gets the length of the control buffer.
796-
///
797-
/// Can be used to determine how much, if any, of the control buffer was filled by `recvmsg`.
798-
///
799-
/// Corresponds to `msg_controllen` on Unix and `Control.len` on Windows.
800-
pub fn control_len(&self) -> usize {
801-
sys::msghdr_control_len(&self.inner.msg_hdr)
802-
}
781+
/// Returns the flags of the message.
782+
pub fn flags(&self) -> RecvFlags {
783+
sys::msghdr_flags(&self.inner.msg_hdr)
803784
}
804785

805-
impl<'addr, 'bufs, 'control> From<MsgHdrMut<'addr, 'bufs, 'control>>
806-
for MMsgHdrMut<'addr, 'bufs, 'control>
807-
{
808-
fn from(value: MsgHdrMut<'_, '_, '_>) -> Self {
809-
Self::new(value)
810-
}
786+
/// Gets the length of the control buffer.
787+
///
788+
/// Can be used to determine how much, if any, of the control buffer was filled by `recvmsg`.
789+
pub fn control_len(&self) -> usize {
790+
sys::msghdr_control_len(&self.inner.msg_hdr)
811791
}
792+
}
812793

813-
impl<'addr, 'bufs, 'control> fmt::Debug for MMsgHdrMut<'addr, 'bufs, 'control> {
814-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
815-
f.write_str("MMsgHdrMut({})", self.len())
816-
}
794+
impl<'addr, 'bufs, 'control> fmt::Debug for MMsgHdrMut<'addr, 'bufs, 'control> {
795+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
796+
f.write_str(&format!("MMsgHdrMut({})", self.recieved_bytes()))
817797
}
818798
}
799+
}

tests/socket.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -771,28 +771,43 @@ fn sendmsg() {
771771

772772
#[test]
773773
#[cfg(any(target_os = "linux", target_os = "android"))]
774-
fn sendmmsg() {
774+
fn send_and_recv_batched_msgs() {
775775
let (socket_a, socket_b) = udp_pair_unconnected();
776776

777777
const DATA: &[u8] = b"Hello, World!";
778778

779-
let bufs = &[IoSlice::new(DATA)];
780779
let addr_b = socket_b.local_addr().unwrap();
781-
let batched_msgs = Vec::new();
782-
for _ in 0..5 {
780+
let mut batched_msgs = Vec::new();
781+
let mut recv_batched_msgs = Vec::new();
782+
for _ in 0..10 {
783+
let bufs = &[IoSlice::new(DATA)];
783784
batched_msgs.push(socket2::MMsgHdr::new(
784785
socket2::MsgHdr::new().with_addr(&addr_b).with_buffers(bufs),
785786
));
787+
788+
let mut buf = [MaybeUninit::new(0u8); 20];
789+
let recv_bufs = MaybeUninitSlice::new(buf.as_mut_slice());
790+
recv_batched_msgs.push(socket2::MMsgHdrMut::new(
791+
socket2::MsgHdrMut::new().with_buffers(&mut [recv_bufs]),
792+
));
786793
}
787794

788795
let sent = socket_a.sendmmsg(batched_msgs.as_mut_slice(), 0).unwrap();
789796

790797
let mut sent_data = 0;
791798
// Calculate transmitted length
792-
for i in 0..5 {
793-
sent_data += batched_msgs[i].transmitted_bytes()
799+
for msg in batched_msgs.iter().take(sent) {
800+
sent_data += msg.transmitted_bytes()
794801
}
795-
assert!(sent_data == 5 * DATA.len());
802+
assert!(sent_data as usize == 10 * DATA.len());
803+
804+
let recvd = socket_b
805+
.recvmmsg(recv_batched_msgs.as_mut_slice(), 0, None)
806+
.unwrap();
807+
808+
assert!(recvd == sent);
809+
810+
assert!(recv_batched_msgs[0].recieved_bytes() == DATA.len().try_into().unwrap());
796811
}
797812

798813
#[test]

0 commit comments

Comments
 (0)