That function could 'return WSAPoll(pfd, nfds, timeout);' but WSAPoll is said to have weird behaviors on the internet (the curl folks have had problems with it). So we make it a select wrapper UPDATE: WSAPoll was fixed in Windows 10 Version 2004 The optional "event" is set to nullptr if it wasn't signaled.
| 102 | // |
| 103 | // The optional "event" is set to nullptr if it wasn't signaled. |
| 104 | int poll(struct pollfd* fds, nfds_t nfds, int timeout, void** event) |
| 105 | { |
| 106 | #ifdef _WIN32 |
| 107 | |
| 108 | if (event && *event) |
| 109 | { |
| 110 | HANDLE interruptEvent = reinterpret_cast<HANDLE>(*event); |
| 111 | *event = nullptr; // the event wasn't signaled yet |
| 112 | |
| 113 | if (nfds < 0 || nfds >= MAXIMUM_WAIT_OBJECTS - 1) |
| 114 | { |
| 115 | WSASetLastError(WSAEINVAL); |
| 116 | return SOCKET_ERROR; |
| 117 | } |
| 118 | |
| 119 | std::vector<WSAEvent> socketEvents; |
| 120 | std::vector<HANDLE> handles; |
| 121 | // put the interrupt event as first element, making it highest priority |
| 122 | handles.push_back(interruptEvent); |
| 123 | |
| 124 | // create the WSAEvents for the sockets |
| 125 | for (nfds_t i = 0; i < nfds; ++i) |
| 126 | { |
| 127 | struct pollfd* fd = &fds[i]; |
| 128 | fd->revents = 0; |
| 129 | if (fd->fd >= 0) |
| 130 | { |
| 131 | // create WSAEvent and add it to the vectors |
| 132 | socketEvents.push_back(std::move(WSAEvent(fd))); |
| 133 | HANDLE handle = socketEvents.back(); |
| 134 | if (handle == WSA_INVALID_EVENT) |
| 135 | { |
| 136 | WSASetLastError(WSAENOBUFS); |
| 137 | return SOCKET_ERROR; |
| 138 | } |
| 139 | handles.push_back(handle); |
| 140 | |
| 141 | // mapping |
| 142 | long networkEvents = 0; |
| 143 | if (fd->events & (POLLIN )) networkEvents |= FD_READ | FD_ACCEPT | FD_CLOSE; |
| 144 | if (fd->events & (POLLOUT /*| POLLWRNORM | POLLWRBAND*/)) networkEvents |= FD_WRITE | FD_CONNECT; |
| 145 | //if (fd->events & (POLLPRI | POLLRDBAND )) networkEvents |= FD_OOB; |
| 146 | |
| 147 | if (WSAEventSelect(fd->fd, handle, networkEvents) != 0) |
| 148 | { |
| 149 | fd->revents = POLLNVAL; |
| 150 | socketEvents.pop_back(); |
| 151 | handles.pop_back(); |
| 152 | } |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | DWORD n = WSAWaitForMultipleEvents(handles.size(), handles.data(), FALSE, timeout != -1 ? static_cast<DWORD>(timeout) : WSA_INFINITE, FALSE); |
| 157 | |
| 158 | if (n == WSA_WAIT_FAILED) return SOCKET_ERROR; |
| 159 | if (n == WSA_WAIT_TIMEOUT) return 0; |
| 160 | if (n == WSA_WAIT_EVENT_0) |
| 161 | { |
no test coverage detected