From owner-freebsd-net@freebsd.org Tue Jan 26 13:40:12 2016 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 76201A46CC3 for ; Tue, 26 Jan 2016 13:40:12 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mailman.ysv.freebsd.org (mailman.ysv.freebsd.org [IPv6:2001:1900:2254:206a::50:5]) by mx1.freebsd.org (Postfix) with ESMTP id 5C2EF116A for ; Tue, 26 Jan 2016 13:40:12 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: by mailman.ysv.freebsd.org (Postfix) id 5BF96A46CC1; Tue, 26 Jan 2016 13:40:12 +0000 (UTC) Delivered-To: net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5A80DA46CC0; Tue, 26 Jan 2016 13:40:12 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DAB131169; Tue, 26 Jan 2016 13:40:11 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id u0QDe65E082213 (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Tue, 26 Jan 2016 15:40:06 +0200 (EET) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua u0QDe65E082213 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id u0QDe5Y8082210; Tue, 26 Jan 2016 15:40:05 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Tue, 26 Jan 2016 15:40:05 +0200 From: Konstantin Belousov To: Boris Astardzhiev Cc: gljennjohn@gmail.com, threads@freebsd.org, Bruce Evans , net@freebsd.org Subject: Re: Does FreeBSD have sendmmsg or recvmmsg system calls? Message-ID: <20160126134005.GD3942@kib.kiev.ua> References: <20160118140811.GW3942@kib.kiev.ua> <20160120073154.GB3942@kib.kiev.ua> <20160121093509.GK3942@kib.kiev.ua> <20160121233040.E1864@besplex.bde.org> <20160124050634.GS3942@kib.kiev.ua> <20160124100747.551f8e3f@ernst.home> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 Jan 2016 13:40:12 -0000 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 > @@ -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