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>