2005-04-06 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mono / utils / mono-poll.c
1 #include "mono-poll.h"
2
3 #ifdef HAVE_POLL
4 int
5 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
6 {
7         return poll (ufds, nfds, timeout);
8 }
9 #else
10
11 int
12 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
13 {
14         struct timeval tv, *tvptr;
15         int i, fd, events, affected, count;
16         fd_set rfds, wfds, efds;
17         int nexc = 0;
18         int maxfd = 0;
19
20         if (timeout < 0) {
21                 tvptr = NULL;
22         } else {
23                 tv.tv_sec = timeout / 1000;
24                 tv.tv_usec = (timeout % 1000) * 1000;
25                 tvptr = &tv;
26         }
27
28         FD_ZERO (&rfds);
29         FD_ZERO (&wfds);
30         FD_ZERO (&efds);
31
32         for (i = 0; i < nfds; i++) {
33                 ufds [i].revents = 0;
34                 fd = ufds [i].fd;
35                 if (fd < 0)
36                         continue;
37
38 #ifdef PLATFORM_WIN32
39                 if (nexc >= FD_SETSIZE) {
40                         ufds [i].revents = MONO_POLLNVAL;
41                         return 1;
42                 }
43 #else
44                 if (fd > FD_SETSIZE) {
45                         ufds [i].revents = MONO_POLLNVAL;
46                         return 1;
47                 }
48 #endif
49
50                 events = ufds [i].events;
51                 if ((events & MONO_POLLIN) != 0)
52                         FD_SET (fd, &rfds);
53
54                 if ((events & MONO_POLLOUT) != 0)
55                         FD_SET (fd, &wfds);
56
57                 FD_SET (fd, &efds);
58                 nexc++;
59                 if (fd > maxfd)
60                         maxfd = fd;
61                         
62         }
63
64         affected = select (maxfd + 1, &rfds, &wfds, &efds, tvptr);
65         if (affected == -1) /* EBADF should be translated to POLLNVAL */
66                 return -1;
67
68         count = 0;
69         for (i = 0; i < nfds && affected > 0; i++) {
70                 fd = ufds [i].fd;
71                 if (fd < 0)
72                         continue;
73
74                 events = ufds [i].events;
75                 if ((events & MONO_POLLIN) != 0 && FD_ISSET (fd, &rfds)) {
76                         ufds [i].revents |= MONO_POLLIN;
77                         affected--;
78                 }
79
80                 if ((events & MONO_POLLOUT) != 0 && FD_ISSET (fd, &wfds)) {
81                         ufds [i].revents |= MONO_POLLOUT;
82                         affected--;
83                 }
84
85                 if (FD_ISSET (fd, &efds)) {
86                         ufds [i].revents |= MONO_POLLERR;
87                         affected--;
88                 }
89
90                 if (ufds [i].revents != 0)
91                         count++;
92         }
93
94         return count;
95 }
96
97 #endif
98