Skip to content

(shuttle-tokio): feat(mpsc): Implement poll_recv for ReceiverInternal - #319

Open
sarsko wants to merge 1 commit into
mainfrom
poll_recv
Open

(shuttle-tokio): feat(mpsc): Implement poll_recv for ReceiverInternal#319
sarsko wants to merge 1 commit into
mainfrom
poll_recv

Conversation

@sarsko

@sarsko sarsko commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

poll_recv was previously unimplemented. The new implementation
stores a persistent Acquire future in ReceiverInternal so the
semaphore waiter stays registered across polls. When the channel
is empty, the caller is properly suspended via the semaphore
waiter queue until a message arrives or the channel closes.

recv, try_recv, and blocking_recv are reimplemented atop poll_recv
so that semaphore interaction is centralized in a single code path.
try_recv polls once with a noop waker and clears the pending acquire
on Pending; recv uses poll_fn; blocking_recv uses block_on(recv).

The Acquire future borrows recv_semaphore behind Arc,
with the lifetime transmuted to 'static. This is sound because
pending_acquire is always cleared before chan is dropped.

Add parity tests for bounded and unbounded poll_recv, plus a test
that interleaves poll_recv with recv to verify no permit leak.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

poll_recv was previously unimplemented. The new implementation
stores a persistent Acquire future in ReceiverInternal so the
semaphore waiter stays registered across polls. When the channel
is empty, the caller is properly suspended via the semaphore
waiter queue until a message arrives or the channel closes.

recv, try_recv, and blocking_recv are reimplemented atop poll_recv
so that semaphore interaction is centralized in a single code path.
try_recv polls once with a noop waker and clears the pending acquire
on Pending; recv uses poll_fn; blocking_recv uses block_on(recv).

The Acquire future borrows recv_semaphore behind Arc<Channel>,
with the lifetime transmuted to 'static. This is sound because
pending_acquire is always cleared before chan is dropped.

Add parity tests for bounded and unbounded poll_recv, plus a test
that interleaves poll_recv with recv to verify no permit leak.

🤖 Assisted by AI

Cherry-picked from ShuttleTokio commit fb6e01b7, with
poll_recv_then_recv_no_leak changed to use a capacity-1 channel so
that a leaked permit is actually observable (it would deadlock the
send) rather than being masked by the spare capacity.
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