Skip to content

Trim fd_set memory, fix timeout math, stop busy-spinning in verify(jwt) - #224

Open
djw8605 wants to merge 1 commit into
scitokens:masterfrom
djw8605:perf/fdset-timeouts-spin
Open

Trim fd_set memory, fix timeout math, stop busy-spinning in verify(jwt)#224
djw8605 wants to merge 1 commit into
scitokens:masterfrom
djw8605:perf/fdset-timeouts-spin

Conversation

@djw8605

@djw8605 djw8605 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Three related I/O-loop cleanups:

1. ~384 KB of fd_sets per in-flight request

SimpleCurlGet declared its select() sets as fd_set m_read_fd_set[FD_SETSIZE] — an array of 1024 fd_sets (×3 members) where a single fd_set (which already holds FD_SETSIZE descriptors) was intended. Roughly 384 KB of wasted memory per SimpleCurlGet, i.e., per in-flight verification. It only worked because the arrays decayed to a pointer to their first element.

2. Timeout math in AsyncStatus::get_timeout_val()

Computed 100 * (seconds remaining) where every other site converts seconds→ms with 1000 (compare SimpleCurlGet::perform). C-API event loops using scitoken_status_get_timeout_val therefore polled 10× more often than intended. It also produced a negative timeval once the deadline passed — invalid for select() (EINVAL). Now 1000 * with a clamp at zero.

3. Busy-spin in verify(jwt)

The verify(const jwt::decoded_jwt&) overload — the path scitoken_deserialize uses — looped verify_async_continue() with no select() at all, pinning a CPU core for the full duration of any JWKS fetch over the network. It now waits on the transfer's descriptors (capped at 1 s) and continues unconditionally afterward, as libcurl requires after timeouts.

Testing

  • ctest unit, env_config, and monitoring suites pass (deserialize tests exercise the reworked loop).

🤖 Generated with Claude Code

Three related I/O-loop cleanups:

- SimpleCurlGet declared its select() sets as fd_set[FD_SETSIZE] --
  arrays of 1024 fd_sets where a single fd_set (which already holds
  FD_SETSIZE descriptors) was intended.  That is roughly 384KB of
  wasted memory per in-flight request; it only worked because the
  arrays decayed to a pointer to their first element.

- AsyncStatus::get_timeout_val() computed 100 * (seconds remaining)
  where every other site converts with 1000, making C-API event loops
  poll 10x more often than intended; it also produced a negative
  timeval once the deadline passed, which is invalid for select()
  (EINVAL).  Use 1000x and clamp at zero.

- The verify(jwt) overload -- the path scitoken_deserialize uses --
  looped verify_async_continue() with no select() at all, pinning a
  CPU core for the full duration of any JWKS fetch.  Wait on the
  transfer's file descriptors (capped at one second, and continuing
  after timeouts as libcurl requires) instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@djw8605 djw8605 added the ai-gen label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant