[runtime] Fixed warning by including <winsock2.h> before <windows.h>.
[mono.git] / mono / utils / mono-poll.c
1 #ifdef HOST_WIN32
2 /* For select */
3 #include <winsock2.h>
4 #endif
5
6 #include "mono-poll.h"
7 #include <errno.h>
8
9 #ifdef DISABLE_SOCKETS
10 #include <glib.h>
11
12 int
13 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
14 {
15         g_assert_not_reached ();
16         return -1;
17 }
18 #else
19
20 #if defined(HAVE_POLL) && !defined(__APPLE__)
21 int
22 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
23 {
24         return poll (ufds, nfds, timeout);
25 }
26 #else
27
28 int
29 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
30 {
31         struct timeval tv, *tvptr;
32         int i, fd, events, affected, count;
33         fd_set rfds, wfds, efds;
34         int nexc = 0;
35         int maxfd = 0;
36
37         if (timeout < 0) {
38                 tvptr = NULL;
39         } else {
40                 tv.tv_sec = timeout / 1000;
41                 tv.tv_usec = (timeout % 1000) * 1000;
42                 tvptr = &tv;
43         }
44
45         FD_ZERO (&rfds);
46         FD_ZERO (&wfds);
47         FD_ZERO (&efds);
48
49         for (i = 0; i < nfds; i++) {
50                 ufds [i].revents = 0;
51                 fd = ufds [i].fd;
52                 if (fd < 0)
53                         continue;
54
55 #ifdef HOST_WIN32
56                 if (nexc >= FD_SETSIZE) {
57                         ufds [i].revents = MONO_POLLNVAL;
58                         return 1;
59                 }
60 #else
61                 if (fd > FD_SETSIZE) {
62                         ufds [i].revents = MONO_POLLNVAL;
63                         return 1;
64                 }
65 #endif
66
67                 events = ufds [i].events;
68                 if ((events & MONO_POLLIN) != 0)
69                         FD_SET (fd, &rfds);
70
71                 if ((events & MONO_POLLOUT) != 0)
72                         FD_SET (fd, &wfds);
73
74                 FD_SET (fd, &efds);
75                 nexc++;
76                 if (fd > maxfd)
77                         maxfd = fd;
78                         
79         }
80
81         affected = select (maxfd + 1, &rfds, &wfds, &efds, tvptr);
82         if (affected == -1) {
83 #ifdef HOST_WIN32
84                 int error = WSAGetLastError ();
85                 switch (error) {
86                 case WSAEFAULT: errno = EFAULT; break;
87                 case WSAEINVAL: errno = EINVAL; break;
88                 case WSAEINTR: errno = EINTR; break;
89                 /* case WSAEINPROGRESS: errno = EINPROGRESS; break; */
90                 case WSAEINPROGRESS: errno = EINTR; break;
91                 case WSAENOTSOCK: errno = EBADF; break;
92 #ifdef ENOSR
93                 case WSAENETDOWN: errno = ENOSR; break;
94 #endif
95                 default: errno = 0;
96                 }
97 #endif
98
99                 return -1;
100         }
101
102         count = 0;
103         for (i = 0; i < nfds && affected > 0; i++) {
104                 fd = ufds [i].fd;
105                 if (fd < 0)
106                         continue;
107
108                 events = ufds [i].events;
109                 if ((events & MONO_POLLIN) != 0 && FD_ISSET (fd, &rfds)) {
110                         ufds [i].revents |= MONO_POLLIN;
111                         affected--;
112                 }
113
114                 if ((events & MONO_POLLOUT) != 0 && FD_ISSET (fd, &wfds)) {
115                         ufds [i].revents |= MONO_POLLOUT;
116                         affected--;
117                 }
118
119                 if (FD_ISSET (fd, &efds)) {
120                         ufds [i].revents |= MONO_POLLERR;
121                         affected--;
122                 }
123
124                 if (ufds [i].revents != 0)
125                         count++;
126         }
127
128         return count;
129 }
130
131 #endif
132
133 #endif /* #ifndef DISABLE_SOCKETS */