| 145 | }; |
| 146 | |
| 147 | int poll(struct pollfd fds[], nfds_t nfds, int timeout) noexcept { |
| 148 | HANDLE rawEvent = WSACreateEvent(); |
| 149 | if (rawEvent == WSA_INVALID_EVENT) { |
| 150 | errno = EIO; |
| 151 | return -1; |
| 152 | } |
| 153 | |
| 154 | TWSAEventHolder event(rawEvent); |
| 155 | |
| 156 | int checked_sockets = 0; |
| 157 | |
| 158 | for (pollfd* fd = fds; fd < fds + nfds; ++fd) { |
| 159 | int win_events = convert_events(fd->events, evpairs_to_win, nevpairs_to_win, false); |
| 160 | if (win_events == -1) { |
| 161 | errno = EINVAL; |
| 162 | return -1; |
| 163 | } |
| 164 | fd->revents = 0; |
| 165 | if (WSAEventSelect(fd->fd, event.Get(), win_events)) { |
| 166 | int error = WSAGetLastError(); |
| 167 | if (error == WSAEINVAL || error == WSAENOTSOCK) { |
| 168 | fd->revents = POLLNVAL; |
| 169 | ++checked_sockets; |
| 170 | } else { |
| 171 | errno = EIO; |
| 172 | return -1; |
| 173 | } |
| 174 | } |
| 175 | fd_set readfds; |
| 176 | fd_set writefds; |
| 177 | struct timeval timeout = {0, 0}; |
| 178 | FD_ZERO(&readfds); |
| 179 | FD_ZERO(&writefds); |
| 180 | if (fd->events & POLLIN) { |
| 181 | FD_SET(fd->fd, &readfds); |
| 182 | } |
| 183 | if (fd->events & POLLOUT) { |
| 184 | FD_SET(fd->fd, &writefds); |
| 185 | } |
| 186 | int error = select(0, &readfds, &writefds, nullptr, &timeout); |
| 187 | if (error > 0) { |
| 188 | if (FD_ISSET(fd->fd, &readfds)) { |
| 189 | fd->revents |= POLLIN; |
| 190 | } |
| 191 | if (FD_ISSET(fd->fd, &writefds)) { |
| 192 | fd->revents |= POLLOUT; |
| 193 | } |
| 194 | ++checked_sockets; |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | if (checked_sockets > 0) { |
| 199 | // returns without wait since we already have sockets in desired conditions |
| 200 | return checked_sockets; |
| 201 | } |
| 202 | |
| 203 | HANDLE events[] = {event.Get()}; |
| 204 | DWORD wait_result = WSAWaitForMultipleEvents(1, events, TRUE, timeout, FALSE); |