Skip to content

Check queue readiness and capacity before waiting - #132

Open
cf-rhett wants to merge 2 commits into
jamesmunns:mainfrom
cf-rhett:fast-ready-waits
Open

Check queue readiness and capacity before waiting#132
cf-rhett wants to merge 2 commits into
jamesmunns:mainfrom
cf-rhett:fast-ready-waits

Conversation

@cf-rhett

@cf-rhett cf-rhett commented Jul 31, 2026

Copy link
Copy Markdown

Summary

Two guards on the async wait paths, one commit each.

The first attempts framed and stream queue operations before entering the async notifier. When the queue is not ready, the methods retain the existing notifier path, including its subscribe-before-recheck ordering. This avoids waker registration and notifier bookkeeping when a grant or frame is already available. A counting notifier test covers every async wait method without relying on timing.

The second handles the case the first cannot: a request larger than the buffer itself. FramedProducer::wait_grant and StreamProducer::wait_grant_exact documented that as "will never return" and parked forever on a size no amount of consumer progress can satisfy. Both now compare against capacity up front and return WriteGrantError::InsufficientSize, which is what the synchronous grant and grant_exact already answer for the same input rather than a second convention for the same condition. Capacity is fixed for the life of the queue, so the comparison happens once, before the wait. wait_grant_max_remaining is unaffected; it caps its ask at what is available.

That second commit changes wait_grant and wait_grant_exact to return Result, so it is an API break. Happy to split it back out if you would rather take the readiness check on its own.

#133 touches this same file, but the only overlap is that both append a test module at the end of framed.rs — whichever lands second needs a keep-both resolution, not a semantic one.

Testing

  • cargo test --features=std
  • cargo build --no-default-features
  • cargo build --features=std
  • cargo build --no-default-features --target=thumbv6m-none-eabi
  • cargo build --target=thumbv6m-none-eabi --features=portable-atomic-unsafe-assume-single-core
  • ./miri.sh
  • cargo clippy --features=std --all-targets -- -D warnings

@titaniumtraveler

Copy link
Copy Markdown

Opportunistically trying to get the grant seems like a good idea, ye.

I kinda wonder why that wasn't the case before/why maitake doesn't do that by itself.

This section in maitake-sync::WaitCell might have something to do with it, but I would have to research the topic a bit more in-depth before being sure on this.

In particular, this function correctly registers interest in the [WaitCell]
prior to polling the function, ensuring that there is not a chance of a race
where the condition occurs AFTER checking but BEFORE registering interest
in the [WaitCell], which could lead to deadlock.

(In particular whether this case is relevant for BBQueue's polling behavior)

@cf-rhett
cf-rhett marked this pull request as ready for review July 31, 2026 15:43
`FramedProducer::wait_grant` and `StreamProducer::wait_grant_exact` park until
a request can be met, but a request larger than the buffer itself cannot be met
by any amount of consumer progress. Both documented that as "will never return"
and left the caller hung on a size the queue could have rejected outright.

The synchronous `grant` and `grant_exact` already answer this exact input with
`WriteGrantError::InsufficientSize`, so the waiting variants now return the same
`Result` rather than growing a second convention for the same condition. The
capacity comparison happens once, before the wait: capacity is fixed for the
lifetime of the queue, so a request that does not fit an empty buffer will never
fit a fuller one.

`wait_grant_max_remaining` is unaffected; it caps its ask at what is available.
@cf-rhett cf-rhett changed the title Check queue readiness before waiting Check queue readiness and capacity before waiting Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants