aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Buehler <tb@openbsd.org>2026-07-17 11:27:09 +0200
committerTheo Buehler <tb@openbsd.org>2026-07-17 11:27:09 +0200
commitef2f80e5c1f7a3a5b04532cdab694a33b8e1ee14 (patch)
tree747bb7ab7457f2b58e5af7e99f10d7bdf36562e2
parent8c68203f0f6069309b3069f7fc829d1bd9564802 (diff)
parent9082d30d64e6765f930dc320addd1fda134a78c1 (diff)
downloadportable-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.c30
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;