Release captured reference type stack variables
[mono-project.git] / mono / utils / mono-poll.c
blobf353fc53af4de7011b548af2edfcd3a91d82824b
1 #include "mono-poll.h"
2 #include <errno.h>
4 #if defined(HAVE_POLL) && !defined(__APPLE__)
5 int
6 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
8 return poll (ufds, nfds, timeout);
10 #else
12 int
13 mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout)
15 struct timeval tv, *tvptr;
16 int i, fd, events, affected, count;
17 fd_set rfds, wfds, efds;
18 int nexc = 0;
19 int maxfd = 0;
21 if (timeout < 0) {
22 tvptr = NULL;
23 } else {
24 tv.tv_sec = timeout / 1000;
25 tv.tv_usec = (timeout % 1000) * 1000;
26 tvptr = &tv;
29 FD_ZERO (&rfds);
30 FD_ZERO (&wfds);
31 FD_ZERO (&efds);
33 for (i = 0; i < nfds; i++) {
34 ufds [i].revents = 0;
35 fd = ufds [i].fd;
36 if (fd < 0)
37 continue;
39 #ifdef HOST_WIN32
40 if (nexc >= FD_SETSIZE) {
41 ufds [i].revents = MONO_POLLNVAL;
42 return 1;
44 #else
45 if (fd > FD_SETSIZE) {
46 ufds [i].revents = MONO_POLLNVAL;
47 return 1;
49 #endif
51 events = ufds [i].events;
52 if ((events & MONO_POLLIN) != 0)
53 FD_SET (fd, &rfds);
55 if ((events & MONO_POLLOUT) != 0)
56 FD_SET (fd, &wfds);
58 FD_SET (fd, &efds);
59 nexc++;
60 if (fd > maxfd)
61 maxfd = fd;
65 affected = select (maxfd + 1, &rfds, &wfds, &efds, tvptr);
66 if (affected == -1) {
67 #ifdef HOST_WIN32
68 int error = WSAGetLastError ();
69 switch (error) {
70 case WSAEFAULT: errno = EFAULT; break;
71 case WSAEINVAL: errno = EINVAL; break;
72 case WSAEINTR: errno = EINTR; break;
73 /* case WSAEINPROGRESS: errno = EINPROGRESS; break; */
74 case WSAEINPROGRESS: errno = EINTR; break;
75 case WSAENOTSOCK: errno = EBADF; break;
76 #ifdef ENOSR
77 case WSAENETDOWN: errno = ENOSR; break;
78 #endif
79 default: errno = 0;
81 #endif
83 return -1;
86 count = 0;
87 for (i = 0; i < nfds && affected > 0; i++) {
88 fd = ufds [i].fd;
89 if (fd < 0)
90 continue;
92 events = ufds [i].events;
93 if ((events & MONO_POLLIN) != 0 && FD_ISSET (fd, &rfds)) {
94 ufds [i].revents |= MONO_POLLIN;
95 affected--;
98 if ((events & MONO_POLLOUT) != 0 && FD_ISSET (fd, &wfds)) {
99 ufds [i].revents |= MONO_POLLOUT;
100 affected--;
103 if (FD_ISSET (fd, &efds)) {
104 ufds [i].revents |= MONO_POLLERR;
105 affected--;
108 if (ufds [i].revents != 0)
109 count++;
112 return count;
115 #endif