rustls-openssl's Signer::sign() is synchronous and blocks the calling thread until OpenSSL returns. That's fine for CPU-bound signing, but it's not a suitable fit when the underlying key is backed by a hardware/optimized-software offload engine (e.g. Intel QAT via qatengine) or any other OpenSSL provider that can pause a long-running operation instead of blocking.
In that case, blocking the handshake thread for the duration of the round-trip defeats the purpose of using an event-driven/async server (one OS thread ends up parked per in-flight handshake instead of being free to drive other connections).
OpenSSL already has a mechanism for this: the ASYNC_JOB API (ASYNC_start_job/ASYNC_pause_job, stackful coroutines). Engines that support it call ASYNC_pause_job() internally when an operation is offloaded to hardware/optimized software library, and register a wait descriptor via ASYNC_WAIT_CTX_get_all_fds() so the caller can poll/select on it instead of blocking.
My proposal:
An opt-in async-jobs Cargo feature (Linux-only) that lets rustls-openssl drive Signer::sign()-equivalent operations as ASYNC_JOB`s instead of always blocking:
- A
PendingSign type wraps a single in-flight ASYNC_JOB. It's thread-affine (OpenSSL's ASYNC_JOBs can only be resumed from the OS thread that started/last resumed them), so PendingSign records its home_thread and returns an error rather than causing UB if polled from the wrong thread.
- Per-thread
ASYNC_init_thread job-pool sizing
- If the engine pauses the job with a wait descriptor registered, that fd is exposed so callers can
poll()/epoll on it instead of busy-looping.
- Falls back to synchronous signing when the feature is disabled (the default) — this is purely additive.
This depends on a corresponding non-blocking signing API on the rustls side (a SignOperation/pending-result type, since rustls::sign::Signer is currently synchronous-only). I'm working on that as a separate proposal to rustls and happy to link it here once it's posted, and the two would need to land roughly together.
Given the size of the changes, I wanted to check with you on the next steps. I will be happy to raise a draft PR for you to take a look.
rustls-openssl's
Signer::sign()is synchronous and blocks the calling thread until OpenSSL returns. That's fine for CPU-bound signing, but it's not a suitable fit when the underlying key is backed by a hardware/optimized-software offload engine (e.g. Intel QAT via qatengine) or any other OpenSSL provider that can pause a long-running operation instead of blocking.In that case, blocking the handshake thread for the duration of the round-trip defeats the purpose of using an event-driven/async server (one OS thread ends up parked per in-flight handshake instead of being free to drive other connections).
OpenSSL already has a mechanism for this: the
ASYNC_JOBAPI (ASYNC_start_job/ASYNC_pause_job, stackful coroutines). Engines that support it callASYNC_pause_job()internally when an operation is offloaded to hardware/optimized software library, and register a wait descriptor viaASYNC_WAIT_CTX_get_all_fds()so the caller can poll/select on it instead of blocking.My proposal:
An opt-in async-jobs Cargo feature (Linux-only) that lets rustls-openssl drive
Signer::sign()-equivalent operations as ASYNC_JOB`s instead of always blocking:PendingSigntype wraps a single in-flightASYNC_JOB. It's thread-affine (OpenSSL'sASYNC_JOBs can only be resumed from the OS thread that started/last resumed them), soPendingSignrecords itshome_threadand returns an error rather than causing UB if polled from the wrong thread.ASYNC_init_threadjob-pool sizingpoll()/epoll on it instead of busy-looping.This depends on a corresponding non-blocking signing API on the rustls side (a
SignOperation/pending-result type, sincerustls::sign::Signeris currently synchronous-only). I'm working on that as a separate proposal to rustls and happy to link it here once it's posted, and the two would need to land roughly together.Given the size of the changes, I wanted to check with you on the next steps. I will be happy to raise a draft PR for you to take a look.