Mail Archives: cygwin/2002/03/16/08:59:33
------=_NextPart_000_0009_01C1CCFA.C5A99480
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: 7bit
Here is the new poll() patch. Now invalid descriptors are recognized
(invalid = positive descriptors including 0 which are not open). If there
are invalid descriptors poll() returns immediately with the count of invalid
descriptors. The timer value is ignored. That's the way Linux handles this
case.
As far as I can see there is only one bug left in this poll() function: If a
descriptor is closed revents is set to POLLIN and not to POLLHUP. That's the
way previous poll() functions worked, too. This shouldn't be a problem as
read() will return 0 and tell the application that the socket can be closed.
I changed the test case, too (see polltest2.c). Hopefully this poll()
doesn't cause any problems any more.
Boris
------=_NextPart_000_0009_01C1CCFA.C5A99480
Content-Type: application/octet-stream;
name="newpoll2.cc"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="newpoll2.cc"
/* poll.cc. Implements poll(2) via usage of select(2) call.=0A=
=0A=
Copyright 2000, 2001 Red Hat, Inc.=0A=
=0A=
This file is part of Cygwin.=0A=
=0A=
This software is a copyrighted work licensed under the terms of the=0A=
Cygwin license. Please consult the file "CYGWIN_LICENSE" for=0A=
details. */=0A=
=0A=
#include "winsup.h"=0A=
#include <sys/time.h>=0A=
#include <sys/poll.h>=0A=
#include <errno.h>=0A=
#include <stdlib.h>=0A=
#include "security.h"=0A=
#include "fhandler.h"=0A=
#include "path.h"=0A=
#include "dtable.h"=0A=
#include "cygerrno.h"=0A=
#include "cygheap.h"=0A=
#include "sigproc.h"=0A=
=0A=
extern "C"=0A=
int=0A=
poll (struct pollfd *fds, unsigned int nfds, int timeout)=0A=
{=0A=
int max_fd =3D 0;=0A=
fd_set *read_fds, *write_fds, *except_fds;=0A=
struct timeval tv =3D { timeout / 1000, (timeout % 1000) * 1000 };=0A=
sigframe thisframe (mainthread);=0A=
=0A=
for (unsigned int i =3D 0; i < nfds; ++i)=0A=
if (fds[i].fd > max_fd)=0A=
max_fd =3D fds[i].fd;=0A=
=0A=
size_t fds_size =3D howmany(max_fd + 1, NFDBITS) * sizeof (fd_mask);=0A=
=0A=
read_fds =3D (fd_set *) alloca (fds_size);=0A=
write_fds =3D (fd_set *) alloca (fds_size);=0A=
except_fds =3D (fd_set *) alloca (fds_size);=0A=
=0A=
if (!read_fds || !write_fds || !except_fds)=0A=
{=0A=
set_errno (ENOMEM);=0A=
return -1;=0A=
}=0A=
=0A=
memset (read_fds, 0, fds_size);=0A=
memset (write_fds, 0, fds_size);=0A=
memset (except_fds, 0, fds_size);=0A=
=0A=
int invalid_fds =3D 0; =0A=
for (unsigned int i =3D 0; i < nfds; ++i) =0A=
{ =0A=
fds[i].revents =3D 0; =0A=
if (!cygheap->fdtab.not_open(fds[i].fd)) =0A=
{ =0A=
if (fds[i].events & POLLIN) =0A=
FD_SET(fds[i].fd, read_fds); =0A=
if (fds[i].events & POLLOUT) =0A=
FD_SET(fds[i].fd, write_fds); =0A=
if (fds[i].events & POLLPRI) =0A=
FD_SET(fds[i].fd, except_fds); =0A=
} =0A=
else if (fds[i].fd >=3D 0) =0A=
{ =0A=
++invalid_fds; =0A=
fds[i].revents =3D POLLNVAL; =0A=
} =0A=
} =0A=
=0A=
if (invalid_fds) =0A=
return invalid_fds; =0A=
=0A=
int ret =3D cygwin_select (max_fd + 1, read_fds, write_fds, =
except_fds, timeout < 0 ? NULL : &tv); =0A=
=0A=
if (ret > 0) =0A=
for (unsigned int i =3D 0; i < nfds; ++i) =0A=
{ =0A=
if (fds[i].fd >=3D 0) =0A=
{ =0A=
if (cygheap->fdtab.not_open(fds[i].fd)) =0A=
fds[i].revents =3D POLLHUP; =0A=
else =0A=
{ =0A=
if (FD_ISSET(fds[i].fd, read_fds)) =0A=
fds[i].revents |=3D POLLIN; =0A=
if (FD_ISSET(fds[i].fd, write_fds)) =0A=
fds[i].revents |=3D POLLOUT; =0A=
if (FD_ISSET(fds[i].fd, read_fds) && FD_ISSET(fds[i].fd, =
write_fds)) =0A=
fds[i].revents |=3D POLLERR; =0A=
if (FD_ISSET(fds[i].fd, except_fds)) =0A=
fds[i].revents |=3D POLLPRI; =0A=
} =0A=
} =0A=
} =0A=
=0A=
return ret; =0A=
}
------=_NextPart_000_0009_01C1CCFA.C5A99480
Content-Type: application/octet-stream;
name="poll.patch2"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="poll.patch2"
--- poll.cc Thu Nov 15 04:25:52 2001=0A=
+++ newpoll2.cc Sat Mar 16 02:06:24 2002=0A=
@@ -26,7 +26,7 @@ int=0A=
poll (struct pollfd *fds, unsigned int nfds, int timeout)=0A=
{=0A=
int max_fd =3D 0;=0A=
- fd_set *open_fds, *read_fds, *write_fds, *except_fds;=0A=
+ fd_set *read_fds, *write_fds, *except_fds;=0A=
struct timeval tv =3D { timeout / 1000, (timeout % 1000) * 1000 };=0A=
sigframe thisframe (mainthread);=0A=
=0A=
@@ -36,63 +36,65 @@ poll (struct pollfd *fds, unsigned int n=0A=
=0A=
size_t fds_size =3D howmany(max_fd + 1, NFDBITS) * sizeof (fd_mask);=0A=
=0A=
- open_fds =3D (fd_set *) alloca (fds_size);=0A=
read_fds =3D (fd_set *) alloca (fds_size);=0A=
write_fds =3D (fd_set *) alloca (fds_size);=0A=
except_fds =3D (fd_set *) alloca (fds_size);=0A=
=0A=
- if (!open_fds || !read_fds || !write_fds || !except_fds)=0A=
+ if (!read_fds || !write_fds || !except_fds)=0A=
{=0A=
set_errno (ENOMEM);=0A=
return -1;=0A=
}=0A=
=0A=
- memset (open_fds, 0, fds_size);=0A=
memset (read_fds, 0, fds_size);=0A=
memset (write_fds, 0, fds_size);=0A=
memset (except_fds, 0, fds_size);=0A=
=0A=
- bool valid_fds =3D false;=0A=
- for (unsigned int i =3D 0; i < nfds; ++i)=0A=
- if (!cygheap->fdtab.not_open (fds[i].fd))=0A=
- {=0A=
- valid_fds =3D true;=0A=
- fds[i].revents =3D 0;=0A=
- FD_SET (fds[i].fd, open_fds);=0A=
- if (fds[i].events & POLLIN)=0A=
- FD_SET (fds[i].fd, read_fds);=0A=
- if (fds[i].events & POLLOUT)=0A=
- FD_SET (fds[i].fd, write_fds);=0A=
- if (fds[i].events & POLLPRI)=0A=
- FD_SET (fds[i].fd, except_fds);=0A=
- }=0A=
- else=0A=
- fds[i].revents =3D POLLNVAL;=0A=
-=0A=
- int ret =3D 0;=0A=
- if (valid_fds)=0A=
- ret =3D cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,=0A=
- timeout < 0 ? NULL : &tv);=0A=
-=0A=
- for (unsigned int i =3D 0; i < nfds; ++i)=0A=
- {=0A=
- if (fds[i].revents =3D=3D POLLNVAL && ret >=3D 0)=0A=
- ret++;=0A=
- else if (cygheap->fdtab.not_open(fds[i].fd))=0A=
- fds[i].revents =3D POLLHUP;=0A=
- else if (ret < 0)=0A=
- fds[i].revents =3D POLLERR;=0A=
- else=0A=
- {=0A=
- fds[i].revents =3D 0;=0A=
- if (FD_ISSET (fds[i].fd, read_fds))=0A=
- fds[i].revents |=3D POLLIN;=0A=
- if (FD_ISSET (fds[i].fd, write_fds))=0A=
- fds[i].revents |=3D POLLOUT;=0A=
- if (FD_ISSET (fds[i].fd, except_fds))=0A=
- fds[i].revents |=3D POLLPRI;=0A=
- }=0A=
- }=0A=
+ int invalid_fds =3D 0; =0A=
+ for (unsigned int i =3D 0; i < nfds; ++i) =0A=
+ { =0A=
+ fds[i].revents =3D 0; =0A=
+ if (!cygheap->fdtab.not_open(fds[i].fd)) =0A=
+ { =0A=
+ if (fds[i].events & POLLIN) =0A=
+ FD_SET(fds[i].fd, read_fds); =0A=
+ if (fds[i].events & POLLOUT) =0A=
+ FD_SET(fds[i].fd, write_fds); =0A=
+ if (fds[i].events & POLLPRI) =0A=
+ FD_SET(fds[i].fd, except_fds); =0A=
+ } =0A=
+ else if (fds[i].fd >=3D 0) =0A=
+ { =0A=
+ ++invalid_fds; =0A=
+ fds[i].revents =3D POLLNVAL; =0A=
+ } =0A=
+ } =0A=
+=0A=
+ if (invalid_fds) =0A=
+ return invalid_fds; =0A=
+=0A=
+ int ret =3D cygwin_select (max_fd + 1, read_fds, write_fds, =
except_fds, timeout < 0 ? NULL : &tv); =0A=
+=0A=
+ if (ret > 0) =0A=
+ for (unsigned int i =3D 0; i < nfds; ++i) =0A=
+ { =0A=
+ if (fds[i].fd >=3D 0) =0A=
+ { =0A=
+ if (cygheap->fdtab.not_open(fds[i].fd)) =0A=
+ fds[i].revents =3D POLLHUP; =0A=
+ else =0A=
+ { =0A=
+ if (FD_ISSET(fds[i].fd, read_fds)) =0A=
+ fds[i].revents |=3D POLLIN; =0A=
+ if (FD_ISSET(fds[i].fd, write_fds)) =0A=
+ fds[i].revents |=3D POLLOUT; =0A=
+ if (FD_ISSET(fds[i].fd, read_fds) && =
FD_ISSET(fds[i].fd, write_fds)) =0A=
+ fds[i].revents |=3D POLLERR; =0A=
+ if (FD_ISSET(fds[i].fd, except_fds)) =0A=
+ fds[i].revents |=3D POLLPRI; =0A=
+ } =0A=
+ } =0A=
+ } =0A=
=0A=
- return ret;=0A=
-}=0A=
+ return ret; =0A=
+} =0A=
\ No newline at end of file=0A=
------=_NextPart_000_0009_01C1CCFA.C5A99480
Content-Type: application/octet-stream;
name="polltest2.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="polltest2.c"
/* gcc -opolltest2 polltest2.c */=20
#include <stdio.h>=20
#include <string.h>=20
#include <poll.h>=20
#include <signal.h>=20
#include <unistd.h>=20
void callback_alarm(int sig) { return; }=20
int main()=20
{=20
struct pollfd p[3];=20
memset(p, 0, sizeof(struct pollfd) * 3);=20
p[0].fd =3D -1;=20
p[1].fd =3D -1;=20
p[2].fd =3D -1;=20
printf("all descriptors are negative - poll() must wait for 2 =
seconds\n");=20
poll(p, 3, 2000);=20
printf("all descriptors are negative - revents for any descriptor must =
be 0: %d, %d, %d\n", p[0].revents, p[1].revents, p[2].revents);=20
p[2].fd =3D 0;=20
printf("no descriptor is ready - poll() must return 0: %d\n", poll(p, =
3, 500));=20
printf("no descriptor is ready - revents for any descriptor must be 0: =
%d, %d, %d\n", p[0].revents, p[1].revents, p[2].revents);=20
signal(SIGALRM, callback_alarm);=20
alarm(1);=20
printf("SIGALRM - poll() must return -1: %d\n", poll(p, 3, 1500));=20
printf("SIGALRM - revents for any descriptor must be 0: %d, %d, %d\n", =
p[0].revents, p[1].revents, p[2].revents);=20
p[1].fd =3D 1000;=20
p[2].fd =3D 1001;=20
printf("2 descriptors are invalid - poll() must return 2 immediately: =
%d\n", poll(p, 3, 10000));=20
printf("2 descriptors are invalid - revents must be POLLNVAL for 2. and =
3. descriptor: %d, %d, %d\n", p[0].revents, p[1].revents, p[2].revents); =
}
------=_NextPart_000_0009_01C1CCFA.C5A99480
Content-Type: text/plain; charset=us-ascii
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
------=_NextPart_000_0009_01C1CCFA.C5A99480--
- Raw text -