Wait until the socket is readable/writable. 1 = ready, 0 = timeout, -1 = error. * Windows uses select() deliberately (WSAPoll has a Won't-Fix bug where * certain socket errors are never reported, which can stall an event loop). */
| 92 | * Windows uses select() deliberately (WSAPoll has a Won't-Fix bug where |
| 93 | * certain socket errors are never reported, which can stall an event loop). */ |
| 94 | static int wait_ready(cbm_sock_t fd, bool writing, int timeout_ms) { |
| 95 | #ifdef _WIN32 |
| 96 | fd_set ready; |
| 97 | fd_set errors; |
| 98 | FD_ZERO(&ready); |
| 99 | FD_ZERO(&errors); |
| 100 | FD_SET(fd, &ready); |
| 101 | FD_SET(fd, &errors); |
| 102 | struct timeval tv; |
| 103 | tv.tv_sec = timeout_ms / 1000; |
| 104 | tv.tv_usec = (timeout_ms % 1000) * 1000; |
| 105 | int rc = select(0, writing ? NULL : &ready, writing ? &ready : NULL, &errors, &tv); |
| 106 | if (rc <= 0) |
| 107 | return rc < 0 ? -1 : 0; |
| 108 | return FD_ISSET(fd, &errors) ? -1 : 1; |
| 109 | #else |
| 110 | struct pollfd pfd; |
| 111 | pfd.fd = fd; |
| 112 | pfd.events = writing ? POLLOUT : POLLIN; |
| 113 | pfd.revents = 0; |
| 114 | int rc = poll(&pfd, 1, timeout_ms); |
| 115 | if (rc < 0) |
| 116 | return errno == EINTR ? 0 : -1; |
| 117 | return rc > 0 ? 1 : 0; |
| 118 | #endif |
| 119 | } |
| 120 | |
| 121 | static int wait_readable(cbm_sock_t fd, int timeout_ms) { |
| 122 | return wait_ready(fd, false, timeout_ms); |
no outgoing calls
no test coverage detected