On Tue, Aug 18, 2020 at 08:31:42AM -0500, Eric Blake wrote:
>+ * under an incompatible license. However Winsock has select so
we
>+ * can write a simple (but slow) emulation of poll using select.
>+ */
>+int
>+poll (struct pollfd *fds, int n, int timeout)
>+{
>+ int i, nfds = 0, r;
>+ fd_set readfds, writefds;
>+ struct timeval tv, *tvp;
>+
>+ FD_ZERO (&readfds);
>+ FD_ZERO (&writefds);
>+
>+ for (i = 0; i < n; ++i) {
>+ if (fds[i].events & POLLIN)
>+ FD_SET (fds[i].fd, &readfds);
>+ if (fds[i].events & POLLOUT)
>+ FD_SET (fds[i].fd, &writefds);
>+ if (fds[i].fd > nfds)
>+ nfds = fds[i].fd;
>+ fds[i].revents = 0;
>+ }
>+ nfds++;
Do we need to make sure that nfds does not exceed the limits of
select? Calling FD_SET on a too-large fd causes memory corruption
(twiddling bits outside of the fixed-length bitset is never good).
Offhand, I didn't know the windows bitset length, but a quick google
found:
https://docs.microsoft.com/en-us/windows/win32/winsock/maximum-number-of-...
where the default limit is 64 unless you set a compile-time macro
prior to winsock2.h.
Interestingly fd_set is not implemented as a bitmask in Windows. It's
a count + list of SOCKETs. And yes, it does search it linearly when
you do FD_CLR(!) So that means we only have to check that n coming
into the function is <= 64. I will add such a test. As a result of
this implementation the nfds parameter of select is not needed, and
indeed the documentation on MSDN notes that it is ignored. So I'll
drop the calculation of nfds entirely.
We only use the poll functions with relatively few fds so this
shouldn't ever be a problem in the server, but maybe a future plugin
will do something crazy so it's good to have the check there.
Thanks,
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW