undo change in mini.c
[mono-project.git] / mono / utils / mono-poll.c
blobc2dd2f2afc4b549b6e782ee96f7e949899392c72
1 /**
2 * \file
3 */
5 #include <config.h>
7 #ifdef HOST_WIN32
8 /* For select */
9 #include <winsock2.h>
10 #endif
12 #include "mono-poll.h"
13 #include <errno.h>
14 #include <mono/utils/mono-errno.h>
16 #ifdef DISABLE_SOCKETS
17 #include <glib.h>
19 int
20 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
22 g_assert_not_reached ();
23 return -1;
25 #else
27 #if defined(HAVE_POLL) && !defined(__APPLE__)
28 int
29 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
31 return poll (ufds, nfds, timeout);
33 #else
35 int
36 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
38 struct timeval tv, *tvptr;
39 int i, fd, events, affected, count;
40 fd_set rfds, wfds, efds;
41 int nexc = 0;
42 int maxfd = 0;
44 if (timeout < 0) {
45 tvptr = NULL;
46 } else {
47 tv.tv_sec = timeout / 1000;
48 tv.tv_usec = (timeout % 1000) * 1000;
49 tvptr = &tv;
52 FD_ZERO (&rfds);
53 FD_ZERO (&wfds);
54 FD_ZERO (&efds);
56 for (i = 0; i < nfds; i++) {
57 ufds [i].revents = 0;
58 fd = ufds [i].fd;
59 if (fd < 0)
60 continue;
62 #ifdef HOST_WIN32
63 if (nexc >= FD_SETSIZE) {
64 ufds [i].revents = MONO_POLLNVAL;
65 return 1;
67 #else
68 if (fd >= FD_SETSIZE) {
69 ufds [i].revents = MONO_POLLNVAL;
70 return 1;
72 #endif
74 events = ufds [i].events;
75 if ((events & MONO_POLLIN) != 0)
76 FD_SET (fd, &rfds);
78 if ((events & MONO_POLLOUT) != 0)
79 FD_SET (fd, &wfds);
81 FD_SET (fd, &efds);
82 nexc++;
83 if (fd > maxfd)
84 maxfd = fd;
88 affected = select (maxfd + 1, &rfds, &wfds, &efds, tvptr);
89 if (affected == -1) {
90 #ifdef HOST_WIN32
91 int error = WSAGetLastError ();
92 switch (error) {
93 case WSAEFAULT: mono_set_errno (EFAULT); break;
94 case WSAEINVAL: mono_set_errno (EINVAL); break;
95 case WSAEINTR: mono_set_errno (EINTR); break;
96 /* case WSAEINPROGRESS: mono_set_errno (EINPROGRESS); break; */
97 case WSAEINPROGRESS: mono_set_errno (EINTR); break;
98 case WSAENOTSOCK: mono_set_errno (EBADF); break;
99 #ifdef ENOSR
100 case WSAENETDOWN: mono_set_errno (ENOSR); break;
101 #endif
102 default: mono_set_errno (0);
104 #endif
106 return -1;
109 count = 0;
110 for (i = 0; i < nfds && affected > 0; i++) {
111 fd = ufds [i].fd;
112 if (fd < 0)
113 continue;
115 events = ufds [i].events;
116 if ((events & MONO_POLLIN) != 0 && FD_ISSET (fd, &rfds)) {
117 ufds [i].revents |= MONO_POLLIN;
118 affected--;
121 if ((events & MONO_POLLOUT) != 0 && FD_ISSET (fd, &wfds)) {
122 ufds [i].revents |= MONO_POLLOUT;
123 affected--;
126 if (FD_ISSET (fd, &efds)) {
127 ufds [i].revents |= MONO_POLLERR;
128 affected--;
131 if (ufds [i].revents != 0)
132 count++;
135 return count;
138 #endif
140 #endif /* #ifndef DISABLE_SOCKETS */