diff options
| author | Theo Buehler <tb@openbsd.org> | 2026-07-17 11:27:09 +0200 |
|---|---|---|
| committer | Theo Buehler <tb@openbsd.org> | 2026-07-17 11:27:09 +0200 |
| commit | ef2f80e5c1f7a3a5b04532cdab694a33b8e1ee14 (patch) | |
| tree | 747bb7ab7457f2b58e5af7e99f10d7bdf36562e2 | |
| parent | 8c68203f0f6069309b3069f7fc829d1bd9564802 (diff) | |
| parent | 9082d30d64e6765f930dc320addd1fda134a78c1 (diff) | |
| download | portable-ef2f80e5c1f7a3a5b04532cdab694a33b8e1ee14.tar.gz portable-ef2f80e5c1f7a3a5b04532cdab694a33b8e1ee14.tar.bz2 portable-ef2f80e5c1f7a3a5b04532cdab694a33b8e1ee14.zip | |
Land #1321 - honor poll timeout for win32
| -rw-r--r-- | apps/openssl/compat/poll_win.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/apps/openssl/compat/poll_win.c b/apps/openssl/compat/poll_win.c index 30f6b60..8e28349 100644 --- a/apps/openssl/compat/poll_win.c +++ b/apps/openssl/compat/poll_win.c | |||
| @@ -166,6 +166,7 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
| 166 | * select machinery | 166 | * select machinery |
| 167 | */ | 167 | */ |
| 168 | fd_set rfds, wfds, efds; | 168 | fd_set rfds, wfds, efds; |
| 169 | fd_set rfds_in, wfds_in, efds_in; | ||
| 169 | int rc; | 170 | int rc; |
| 170 | int num_sockets; | 171 | int num_sockets; |
| 171 | 172 | ||
| @@ -249,15 +250,36 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
| 249 | wait_rc = WAIT_FAILED; | 250 | wait_rc = WAIT_FAILED; |
| 250 | 251 | ||
| 251 | looptime_ms = (timeout_ms > 100 || timeout_ms == -1) ? 100 : timeout_ms; | 252 | looptime_ms = (timeout_ms > 100 || timeout_ms == -1) ? 100 : timeout_ms; |
| 252 | if (timeout_ms == -1) | 253 | |
| 253 | timeout_ms = INFINITE; | 254 | /* |
| 255 | * select() clears every descriptor that is not ready from the | ||
| 256 | * fd_sets, so a pass that times out leaves them empty. Keep a | ||
| 257 | * pristine copy and restore it before each select(), otherwise the | ||
| 258 | * next pass hands select() three empty sets and Windows fails it with | ||
| 259 | * WSAEINVAL instead of waiting out the remaining timeout. | ||
| 260 | */ | ||
| 261 | rfds_in = rfds; | ||
| 262 | wfds_in = wfds; | ||
| 263 | efds_in = efds; | ||
| 254 | 264 | ||
| 255 | do { | 265 | do { |
| 256 | TIMEVAL tv; | 266 | TIMEVAL tv; |
| 267 | |||
| 268 | /* | ||
| 269 | * Cap the wait at the time remaining so the final pass | ||
| 270 | * does not overshoot the requested timeout. | ||
| 271 | */ | ||
| 272 | if (timeout_ms != -1 && timeout_ms - timespent_ms < looptime_ms) | ||
| 273 | looptime_ms = timeout_ms - timespent_ms; | ||
| 274 | |||
| 257 | tv.tv_sec = 0; | 275 | tv.tv_sec = 0; |
| 258 | tv.tv_usec = looptime_ms * 1000; | 276 | tv.tv_usec = looptime_ms * 1000; |
| 259 | int handle_signaled = 0; | 277 | int handle_signaled = 0; |
| 260 | 278 | ||
| 279 | rfds = rfds_in; | ||
| 280 | wfds = wfds_in; | ||
| 281 | efds = efds_in; | ||
| 282 | |||
| 261 | /* | 283 | /* |
| 262 | * Check if any file handles have signaled | 284 | * Check if any file handles have signaled |
| 263 | */ | 285 | */ |
| @@ -280,7 +302,7 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
| 280 | /* | 302 | /* |
| 281 | * If we signaled on a file handle, don't wait on the sockets. | 303 | * If we signaled on a file handle, don't wait on the sockets. |
| 282 | */ | 304 | */ |
| 283 | if (wait_rc >= WAIT_OBJECT_0 && | 305 | if (num_handles && wait_rc >= WAIT_OBJECT_0 && |
| 284 | (wait_rc <= WAIT_OBJECT_0 + num_handles - 1)) { | 306 | (wait_rc <= WAIT_OBJECT_0 + num_handles - 1)) { |
| 285 | tv.tv_usec = 0; | 307 | tv.tv_usec = 0; |
| 286 | handle_signaled = 1; | 308 | handle_signaled = 1; |
| @@ -298,7 +320,7 @@ poll(struct pollfd *pfds, nfds_t nfds, int timeout_ms) | |||
| 298 | 320 | ||
| 299 | timespent_ms += looptime_ms; | 321 | timespent_ms += looptime_ms; |
| 300 | 322 | ||
| 301 | } while (timespent_ms < timeout_ms); | 323 | } while (timeout_ms == -1 || timespent_ms < timeout_ms); |
| 302 | 324 | ||
| 303 | rc = 0; | 325 | rc = 0; |
| 304 | num_handles = 0; | 326 | num_handles = 0; |
