[amd64] Fix mingw-w64 build. (#4519)
[mono-project.git] / mono / utils / mono-poll.c
blobd81b4eb9168f050626d4afd5ab31628fd5d061fa
1 #include <config.h>
3 #ifdef HOST_WIN32
4 /* For select */
5 #include <winsock2.h>
6 #endif
8 #include "mono-poll.h"
9 #include <errno.h>
11 #ifdef DISABLE_SOCKETS
12 #include <glib.h>
14 int
15 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
17 g_assert_not_reached ();
18 return -1;
20 #else
22 #if defined(HAVE_POLL) && !defined(__APPLE__)
23 int
24 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
26 return poll (ufds, nfds, timeout);
28 #else
30 int
31 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
33 struct timeval tv, *tvptr;
34 int i, fd, events, affected, count;
35 fd_set rfds, wfds, efds;
36 int nexc = 0;
37 int maxfd = 0;
39 if (timeout < 0) {
40 tvptr = NULL;
41 } else {
42 tv.tv_sec = timeout / 1000;
43 tv.tv_usec = (timeout % 1000) * 1000;
44 tvptr = &tv;
47 FD_ZERO (&rfds);
48 FD_ZERO (&wfds);
49 FD_ZERO (&efds);
51 for (i = 0; i < nfds; i++) {
52 ufds [i].revents = 0;
53 fd = ufds [i].fd;
54 if (fd < 0)
55 continue;
57 #ifdef HOST_WIN32
58 if (nexc >= FD_SETSIZE) {
59 ufds [i].revents = MONO_POLLNVAL;
60 return 1;
62 #else
63 if (fd >= FD_SETSIZE) {
64 ufds [i].revents = MONO_POLLNVAL;
65 return 1;
67 #endif
69 events = ufds [i].events;
70 if ((events & MONO_POLLIN) != 0)
71 FD_SET (fd, &rfds);
73 if ((events & MONO_POLLOUT) != 0)
74 FD_SET (fd, &wfds);
76 FD_SET (fd, &efds);
77 nexc++;
78 if (fd > maxfd)
79 maxfd = fd;
83 affected = select (maxfd + 1, &rfds, &wfds, &efds, tvptr);
84 if (affected == -1) {
85 #ifdef HOST_WIN32
86 int error = WSAGetLastError ();
87 switch (error) {
88 case WSAEFAULT: errno = EFAULT; break;
89 case WSAEINVAL: errno = EINVAL; break;
90 case WSAEINTR: errno = EINTR; break;
91 /* case WSAEINPROGRESS: errno = EINPROGRESS; break; */
92 case WSAEINPROGRESS: errno = EINTR; break;
93 case WSAENOTSOCK: errno = EBADF; break;
94 #ifdef ENOSR
95 case WSAENETDOWN: errno = ENOSR; break;
96 #endif
97 default: errno = 0;
99 #endif
101 return -1;
104 count = 0;
105 for (i = 0; i < nfds && affected > 0; i++) {
106 fd = ufds [i].fd;
107 if (fd < 0)
108 continue;
110 events = ufds [i].events;
111 if ((events & MONO_POLLIN) != 0 && FD_ISSET (fd, &rfds)) {
112 ufds [i].revents |= MONO_POLLIN;
113 affected--;
116 if ((events & MONO_POLLOUT) != 0 && FD_ISSET (fd, &wfds)) {
117 ufds [i].revents |= MONO_POLLOUT;
118 affected--;
121 if (FD_ISSET (fd, &efds)) {
122 ufds [i].revents |= MONO_POLLERR;
123 affected--;
126 if (ufds [i].revents != 0)
127 count++;
130 return count;
133 #endif
135 #endif /* #ifndef DISABLE_SOCKETS */