Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Jan 2016 15:40:05 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Boris Astardzhiev <boris.astardzhiev@gmail.com>
Cc:        gljennjohn@gmail.com, threads@freebsd.org, Bruce Evans <brde@optusnet.com.au>, net@freebsd.org
Subject:   Re: Does FreeBSD have sendmmsg or recvmmsg system calls?
Message-ID:  <20160126134005.GD3942@kib.kiev.ua>
In-Reply-To: <CAP=KkTyHG9Rb%2BnrDC1TDxzjUQFca9NkVp8Suo1c_-C00RUtkuQ@mail.gmail.com>
References:  <20160118140811.GW3942@kib.kiev.ua> <CAP=KkTzLCOnJVqt5F3ZuuZUiwkmWcne2Ynpi6-daE2jTzSBtfw@mail.gmail.com> <20160120073154.GB3942@kib.kiev.ua> <CAP=KkTx3dAUuSBrJiwNAAe%2BhHSG4j5Qp7sAcgtOgmVi8a12k1A@mail.gmail.com> <20160121093509.GK3942@kib.kiev.ua> <20160121233040.E1864@besplex.bde.org> <CAP=KkTw=ML=oPo2OgFfmor_nsL3om6HvmTQjKNMrOiU_dmWc2g@mail.gmail.com> <20160124050634.GS3942@kib.kiev.ua> <20160124100747.551f8e3f@ernst.home> <CAP=KkTyHG9Rb%2BnrDC1TDxzjUQFca9NkVp8Suo1c_-C00RUtkuQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Jan 25, 2016 at 11:22:13AM +0200, Boris Astardzhiev wrote:
> +ssize_t
> +recvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags,
> +    const struct timespec *__restrict timeout)
> +{
> +	size_t i, rcvd;
> +	ssize_t ret;
> +
> +	if (timeout != NULL) {
> +		fd_set fds;
> +		int res;
Please move all local definitions to the beginning of the function.

> +
> +		FD_ZERO(&fds);
> +		FD_SET(s, &fds);
> +		res = __sys_pselect(s + 1, &fds, NULL, NULL, timeout, NULL);
So why is this __sys_pselect() and not pselect() ?

Note that ppoll() is immune to the issue of s > FD_SETSIZE.

> +		if (res == -1 || res == 0)
> +			return (res);
> +		if (!FD_ISSET(s, &fds))
> +			return (-1);
> +	}
> +
> +	ret = __sys_recvmsg(s, &msgvec[0].msg_hdr, flags);
> +	if (ret == -1)
> +		return (ret);
> +
> +	/* Check initially for the presence of MSG_WAITFORONE.
> +	 * Turn on MSG_DONTWAIT if set. */
The style-conformant multi-line comment is
	/*
	 * Text.
	 * More text.
	 */
> +	if (flags & MSG_WAITFORONE) {
> +		flags |= MSG_DONTWAIT;
> +		/* The kernel doesn't need to know about this flag. */
> +		flags &= ~MSG_WAITFORONE;
You clear MSG_WAITFORONE flag in the calls to recvmsg(), but not at
the first recvmsg() incantation.  I think the flag should be just kept alone.

> +	}
> +
> +	rcvd = 1;
> +	for (i = rcvd; i < vlen; i++, rcvd++) {
> +		ret = __sys_recvmsg(s, &msgvec[i].msg_hdr, flags);
> +		if (ret == -1) {
> +			/* We have received messages. Let caller know. */
> +			return (rcvd);
> +		}
> +
> +		/* Save received bytes */
> +		msgvec[i].msg_len = ret;
> +	}
> +
> +	return (rcvd);
> +}

> diff --git a/sys/sys/socket.h b/sys/sys/socket.h
> index 18e2de1..c7a21cc 100644
> --- a/sys/sys/socket.h
> +++ b/sys/sys/socket.h
> @@ -431,6 +431,9 @@ struct msghdr {
>  #define	MSG_NBIO	0x4000		/* FIONBIO mode, used by fifofs */
>  #define	MSG_COMPAT      0x8000		/* used in sendit() */
>  #define	MSG_CMSG_CLOEXEC 0x40000	/* make received fds close-on-exec */
> +#ifndef _KERNEL
Why is the !KERNEL protection for the definition needed ?

> +#define MSG_WAITFORONE	0x80000		/* for recvmmsg() */
> +#endif /* !_KERNEL */
>  #endif
>  #ifdef _KERNEL
>  #define	MSG_SOCALLBCK   0x10000		/* for use by socket callbacks - soreceive (TCP) */
> @@ -595,6 +598,18 @@ struct sf_hdtr {
>  #endif /* _KERNEL */
>  #endif /* __BSD_VISIBLE */
>  
> +#ifndef _KERNEL
Why is the !KERNEL protection for the definition needed ?

> +#ifdef __BSD_VISIBLE
> +/*
> + * Send/recvmmsg specific structure(s)
> + */
> +struct mmsghdr {
> +	struct msghdr	msg_hdr;		/* message header */
> +	ssize_t		msg_len;		/* message length */
> +};
> +#endif /* __BSD_VISIBLE */
> +#endif /* !_KERNEL */
> +
>  #ifndef	_KERNEL
>  
>  #include <sys/cdefs.h>
> @@ -615,11 +630,19 @@ int	listen(int, int);
>  ssize_t	recv(int, void *, size_t, int);
>  ssize_t	recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict);
>  ssize_t	recvmsg(int, struct msghdr *, int);
> +#if __BSD_VISIBLE
> +struct timespec;
> +ssize_t	recvmmsg(int, struct mmsghdr * __restrict, size_t, int,
> +    const struct timespec * __restrict);
> +#endif
>  ssize_t	send(int, const void *, size_t, int);
>  ssize_t	sendto(int, const void *,
>  	    size_t, int, const struct sockaddr *, socklen_t);
>  ssize_t	sendmsg(int, const struct msghdr *, int);
>  #if __BSD_VISIBLE
> +ssize_t	sendmmsg(int, struct mmsghdr * __restrict, size_t, int);
> +#endif
> +#if __BSD_VISIBLE
Again, there is no use in closing __BSD_VISIBLE block only to open
it again on the next line.

>  int	sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
>  int	setfib(int);
>  #endif




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160126134005.GD3942>