On Fri, Dec 20, 2019 at 01:25:29AM +0000, Yi Yang (杨�D)-云服务集团 wrote:
> Current ovs matser has included sendmmsg declaration in
> include/sparse/sys/socket.h
I believe you are mistaken.
> int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
>
> I saw "+^L" in your patch.
Yes, OVS uses page breaks to separate logical sections of code. The
coding style document mentions this.
> --- a/lib/socket-util.c
> +++ b/lib/socket-util.c
> @@ -1283,3 +1283,59 @@ wrap_sendmmsg(int fd, struct mmsghdr *msgs, unsigned
> int n, unsigned int flags)
> }
> #endif
> #endif
> +^L
> +#ifndef _WIN32 /* Avoid using recvmsg on Windows entirely. */
>
> +#undef recvmmsg
> +int
> +wrap_recvmmsg(int fd, struct mmsghdr *msgs, unsigned int n,
> + int flags, struct timespec *timeout)
> +{
> + ovs_assert(!timeout); /* XXX not emulated */
> +
> + static bool recvmmsg_broken = false;
> + if (!recvmmsg_broken) {
> + int save_errno = errno;
> + int retval = recvmmsg(fd, msgs, n, flags, timeout);
> + if (retval >= 0 || errno != ENOSYS) {
> + return retval;
> + }
> + recvmmsg_broken = true;
> + errno = save_errno;
> + }
> + return emulate_recvmmsg(fd, msgs, n, flags, timeout);
> +}
> +#endif
>
> I don't understand why call recvmmsg here although we have known recvmmsg
> isn't defined,
Can you explain that comment? I don't believe that the code tries to
call recvmmsg() when it is not defined. The code inside #ifndef
HAVE_SENDMMSG only uses emulate_recvmmsg(), which itself only calls
recvmsg(), not recvmmsg().
> I don't think "static bool recvmmsg_broken" is thread-safe.
It is thread-safe enough, because it is merely an optimization: if the
value is wrong, then at most the code gets a little bit slower.
> I think we can completely remove the below part if we do know recvmmsg
> isn't defined (I think autoconf can detect it very precisely, we
> needn't to do runtime check for this)
> + static bool recvmmsg_broken = false;
> + if (!recvmmsg_broken) {
> + int save_errno = errno;
> + int retval = recvmmsg(fd, msgs, n, flags, timeout);
> + if (retval >= 0 || errno != ENOSYS) {
> + return retval;
> + }
> + recvmmsg_broken = true;
> + errno = save_errno;
> + }
There are three cases:
1. The C library does not have recvmmsg(). Then we cannot call it at
all. In this case, HAVE_SENDMMSG is false and the "#ifndef
HAVE_SENDMMSG" fork will use emulate_recvmmsg().
2. The C library has recvmmsg() but the kernel does not, because it is
too old. Then wrap_recvmmsg() will receive an ENOSYS error from the
kernel, call emulate_recvmmsg(), and set recvmmsg_broken so that
future calls don't have to bother going into the kernel at all.
3. The C library and the kernel both have recvmmsg(). Then
wrap_recvmmsg() will call recvmmsg() and either succeed or get back
some error other than ENOSYS. recvmmsg_broken will remain false, and
all future calls to recvmmsg() will also take the kernel fast path.
Autoconf cannot distinguish cases 2 and 3, nor can anything that runs at
build time, because there is no way to guess whether the runtime kernel
matches the build time kernel.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev