Add windows-waitable-queues, bounded queues waitable as a HANDLE - #59
Conversation
…e shapes with a shared doorbell Bounded producer/consumer queues whose readiness is a waitable Windows `HANDLE`, so a consumer can park on a queue and a kernel object in the same wait. That is the property none of Rust's existing queue crates offers on Windows: `crossbeam-channel` blocks on its own internal primitive and exposes no handle, and `crossbeam-queue` does not block at all, so a thread that must wake on "a message arrived or my I/O completed or shutdown was signalled" cannot express the wait. Four shapes, each with the capability traits its abilities justify: - `spsc`, a bounded ring with no compare-and-swap on either side. - `slotwise_mpsc`, a bounded array queue on Vyukov's sequence protocol. - `reserving_mpsc`, that queue plus claiming a slot in advance, for a message that must not be lost. - `permit_mpsc`, an experimental claim protocol behind a non-default feature, outside the semver promise until it is merged or deleted. `reserving_mpsc` packs its claim position beside a reservation count in one word, and how those bits divide is a caller's choice. The reservation half is bounded in practice by how many producers are mid-send -- hundreds -- yet the obvious split gives it 2^32, paying for a ceiling nobody reaches with the whole of the claim position's headroom. `Balanced` (32/32), `Enduring` (16/48) and `Perpetual` (8/56) trade that ceiling for a position that lasts from about 37 seconds to about 20 years of sustained maximum-rate pushing, and they issue the same exchange on the same `u64` -- measured indistinguishable outside noise. The opt-in `dwcas` feature adds `Wide`, a 128-bit word that removes the recurrence outright at 2-4x the cost on the claim; it is the only thing here that needs a third-party dependency, since the standard library has no 128-bit atomic. The default stays `Balanced` and is documented as *not* the recommended layout, so the choice is visible rather than made silently. Verified: 289 tests by default, 319 with all features, 12 doctests including the README, which is compiled so an example cannot rot into teaching a name that no longer exists. Clippy clean under `-D warnings` in every feature configuration, and rustdoc clean under CI's flags both with and without `dwcas`, which is where a link to a feature-gated item would otherwise have gone unnoticed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t eight published queue crates Of seventeen capabilities present in three or more of crossbeam-channel, crossbeam-queue, flume, thingbuf, ringbuf, rtrb, concurrent-queue and std::sync::mpsc, this crate has nine and uses the majority spelling for each. Three gaps remain and all are breaking, so they are queued now while the crate is unpublished at 0.0.1. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nished one Closes the public-surface gaps found by comparing this crate against the eight most-depended-on Rust queue crates. Of seventeen capabilities present in three or more of them, this crate already had nine, under the majority spelling in every case. Three were missing. **`pop` returns `Result<T, TryRecvError>` rather than `Option<T>`.** The strongest argument was internal rather than comparative: `push` already distinguished `Full` from `Disconnected` and `recv` already returned `RecvError::Disconnected`; only `pop` collapsed the two. The five crates that distinguish these are the five that are channel-shaped; the three that do not -- crossbeam-queue, rtrb, ringbuf -- have no handles and no disconnection concept, so they have nothing to distinguish. This crate has both. It also removes a protocol nothing could enforce. The `Consumer` trait documented "ask only after `pop` has returned `None`... the only order that cannot lose an item", which is a `TryRecvError` written as prose. The check is now made in that order by construction, and only on the empty path, so a successful take pays nothing for it. **`is_full` moves onto the `Bounded` trait** with a default in terms of `remaining`, and gains an inherent form on each consumer. It was an inherent method on every producer and nowhere else, so generic code could not ask it and a consumer could not either -- while `remaining`, being on the trait, worked everywhere but was spelled out inherently on only one shape. **`try_iter` joins `drain`, both inherent.** Same iterator; `drain` describes the semantics and `try_iter` is the name four of the eight crates use. Previously trait-only, so `rx.drain()` did not compile without importing `Consumer` -- an unused-import warning on an existing test is what proved that fixed. The arming-protocol examples get shorter and safer: the drain loop now reports *why* it ended, so the separate `is_disconnected` check and the second drain loop after it collapse into one match that cannot be written in the wrong order. Deliberately not added, because the comparison showed them to be one- or two-crate features rather than expectations: an explicit `close()` (1/8), `peek` (2/8, and no MPMC crate offers it), bulk transfers (2/8, both single-producer), async (2/8), `force_push` (2/8), `sender_count` (1/8), weak handles (1/8). Five new tests cover the added surface, and converting the existing 138 call sites was itself the check: converting every `None` to `Empty` and running the suite surfaced exactly five assertions that meant `Disconnected` -- all in tests whose names say so, and all cases the old signature could not express. 324 tests with all features, 294 by default, 12 doctests. Clippy clean under `-D warnings` in every feature configuration, rustdoc clean under CI's flags both with and without `dwcas`. Completed item: API-1: Make pop distinguish an empty queue from a departed producer Completed item: API-2: Put is_full on the Bounded trait Completed item: API-3: Add try_iter and IntoIterator on the consumers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ce the shapes The opening said 'Status: three shapes, all waitable' and named them by their internal spellings before the reader knew what the crate was for or why there would be more than one. It also undercounted: permit_mpsc is a fourth, behind a feature. Now: the problem (a Windows thread must wait on several things, and a HANDLE is the universal currency, but a queue is the one thing in that list that is not one), then the approach, then the shapes as a table saying what each adds and when to choose it. Two stale things surfaced while restructuring. A link pointed at a heading renamed during the D-36 sweep, and the choosing-between guidance it led to still said to switch shapes to avoid the recurrence -- advice that predates the layouts. That section was missed by that sweep. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…the handle The previous opening began at the multi-wait problem, which assumes the reader already accepts that a queue must block and that blocking is where the design decision lives. Now the arc is: what a bounded ring is and what it is for; the moment the consumer finds it empty and must sleep on something; that every queue picks a private primitive for that, which is right until the thread is waiting for more than one thing; and only then the handle as this crate's contribution. Also folded a redundant sub-heading that teased a section six lines below it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…repository The README, PLANS.md, error.rs, permit_mpsc.rs and DESIGN-NOTES.md all linked to workspace-root checklists that this crate does not ship with, so every one of those links was broken for a reader of the published crate. Twenty-six in total. Where the reference was to future work, it is now an acknowledgement that the issue exists and is under consideration -- shapes with many consumers, and shapes that signal when space becomes available. Where it was provenance in a decision record, the work-item id is kept as text and only the dangling link removed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A full `cargo mutants` sweep of the crate: 871 mutants, 447 caught, 23 missed, 154 timeouts, 247 unviable. The 23 survivors sorted into three groups. **The new API surface was tested on one shape and not the others.** Every shape implements `pop` and the `Bounded` accessors separately, so the tests written for `slotwise_mpsc` said nothing about the rest -- and the sweep found exactly that: `spsc` and `reserving_mpsc` had an uncovered `Consumer::is_full`, and `reserving_mpsc` an uncovered disconnection guard in `pop`. Repeated per shape, with two additions specific to `reserving_mpsc`: that an outstanding reservation holds the stream open so `pop` reports `Empty` rather than `Disconnected`, and that `is_full` counts a reservation as occupancy, which is why it derives from `remaining` rather than `len`. **`TryRecvError` was absent from the test that enumerates every error's `Display`**, so its rendering could be replaced by the empty string unnoticed. **`permit_mpsc`'s consumer accessors were untested entirely** -- `capacity`, `is_empty`, `refused` and `is_disconnected` could each be replaced by a constant. It is experimental, but a caller who enables the feature gets the same surface as the shipping shapes and is owed the same evidence. Two of those needed more than an assertion. The `Drop` impls decrement a count *and* signal the doorbell, and only the count is publicly observable, so tests written against `is_disconnected` left `== 1` -> `!= 1` alive in both. Worse, the signal is a no-op until a handle has been requested and this shape exposes no way to request one -- so the ring is unreachable through its public surface altogether. The tests ask for the handle through the shared state, which makes the signalling testable now and correct in advance of the shape gaining the waitable surface its siblings have. **A refactor orphaned two equivalent-mutant notes.** The `|` in `claim_word` could equally be `^` because the halves are disjoint, and that was recorded -- but making the word a type parameter moved the operation into `ClaimWord::pack`, leaving the note on the caller. Recorded at both `pack` impls now, along with `zeroed`, where `AtomicU64::new(0)` and `default()` are the same value. Re-running the sweep over the touched files confirms the fixes rather than assuming them: `permit_mpsc` and `error` went from 10 missed to **0**, and the `is_full` and `pop` mutants in `spsc` and `reserving_mpsc` are now caught. The four survivors that remain are the documented equivalents. **The 154 timeouts are not gaps**, and that was verified rather than assumed. Re-injecting `validate_capacity -> Ok(())` -- one of them -- fails six tests immediately, including `a_zero_capacity_is_refused_because_it_could_never_accept_anything`. The mutant is caught decisively; it was recorded as a timeout only because another test in the same process hung and stopped the harness reporting, which is the expected shape in a crate of blocking APIs. 344 tests with all features, 304 by default, 12 doctests. Clippy clean under `-D warnings` in every feature configuration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Release automation is incomplete because publish-crate.yml is not updated to include windows-waitable-queues in tag triggers, dispatch choices, and the workspace-crate allowlist.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds a new publishable workspace crate, windows-waitable-queues, providing bounded queue shapes whose readiness is exposed as a waitable Windows HANDLE (via a lazily-created manual-reset event), and wires it into release-please/versioning.
Changes:
- Add the
windows-waitable-queuescrate (queue shapes, doorbell/arming protocol, error model, options/metrics/disposal, and extensive tests). - Add planning/design docs and sabotage configuration for the new crate.
- Wire the new crate into the workspace membership and release-please config/manifest.
File summaries
| File | Description |
|---|---|
| Cargo.lock | Adds lock entries for the new crate and its dependencies. |
| Cargo.toml | Adds crates/windows-waitable-queues to the workspace members. |
| .release-please-manifest.json | Adds windows-waitable-queues version tracking to the release-please manifest. |
| release-please-config.json | Adds windows-waitable-queues to release-please package configuration. |
| crates/windows-waitable-queues/Cargo.toml | New crate manifest (publishable, Windows-only docs.rs target, optional dwcas feature). |
| crates/windows-waitable-queues/README.md | New crate README (public-facing overview and examples). |
| crates/windows-waitable-queues/DESIGN-NOTES.md | Design decisions for the crate’s contracts and internal architecture. |
| crates/windows-waitable-queues/PLANS.md | Plan index for the new crate. |
| crates/windows-waitable-queues/COMPLETED-PLANS.md | Records completed checklist work for this crate. |
| crates/windows-waitable-queues/COMPLETED-CHECKLIST.md | Archived checklist items describing completed API-surface work. |
| crates/windows-waitable-queues/sabotage.json | Sabotage/mutation configuration for validating correctness properties. |
| crates/windows-waitable-queues/design-sessions/DESIGN-SESSION-2026-09-02-claim-protocol-prior-art.md | Design session record for claim-protocol prior art and ABA hazard survey. |
| crates/windows-waitable-queues/src/lib.rs | Crate root: public API surface, module wiring, exports. |
| crates/windows-waitable-queues/src/traits.rs | Public capability traits (Producer, Consumer, Bounded, Waitable, etc.). |
| crates/windows-waitable-queues/src/traits/tests.rs | Tests for capability traits and trait-provided behavior. |
| crates/windows-waitable-queues/src/error.rs | Shared error types and their contracts/rendering. |
| crates/windows-waitable-queues/src/error/tests.rs | Tests for error rendering, sources, and retryability predicates. |
| crates/windows-waitable-queues/src/capacity.rs | Capacity validation and shared bounds constants. |
| crates/windows-waitable-queues/src/capacity/tests.rs | Tests for capacity bounds and validation edge cases. |
| crates/windows-waitable-queues/src/options.rs | Construction options (disposal policy, high-water tracking) and Debug rendering. |
| crates/windows-waitable-queues/src/options/tests.rs | Tests for options rendering/behavior. |
| crates/windows-waitable-queues/src/metrics.rs | Shared metrics counters (refusals, optional high-water). |
| crates/windows-waitable-queues/src/metrics/tests.rs | Tests for metrics arithmetic/concurrency behavior. |
| crates/windows-waitable-queues/src/disposal.rs | Disposal/teardown policy for undrained items (including panic resilience). |
| crates/windows-waitable-queues/src/disposal/tests.rs | Tests for disposal/teardown semantics and panic handling. |
| crates/windows-waitable-queues/src/doorbell.rs | Doorbell implementation (lazy manual-reset event + correctness fences). |
| crates/windows-waitable-queues/src/doorbell/tests.rs | Tests for doorbell laziness/level semantics and race windows. |
| crates/windows-waitable-queues/src/race_hooks.rs | Test-only hook infrastructure to deterministically drive race windows. |
| crates/windows-waitable-queues/src/race_hooks/tests.rs | Tests for the hook facility itself (unwind safety, re-entrancy). |
| crates/windows-waitable-queues/src/blocking.rs | Shared blocking receive loops (recv / recv_timeout) over an internal trait. |
| crates/windows-waitable-queues/src/blocking/tests.rs | Tests for timeout arithmetic and the internal parked contract. |
| crates/windows-waitable-queues/src/spsc.rs | SPSC queue shape implementation and public constructors/handles. |
| crates/windows-waitable-queues/src/spsc/tests.rs | SPSC-specific correctness and behavior tests. |
| crates/windows-waitable-queues/src/slotwise_mpsc.rs | Slotwise MPSC queue shape implementation. |
| crates/windows-waitable-queues/src/slotwise_mpsc/tests.rs | Slotwise MPSC-specific correctness and behavior tests. |
| crates/windows-waitable-queues/src/reserving_mpsc.rs | Reserving MPSC queue shape (reservation/claim protocol variants). |
| crates/windows-waitable-queues/src/reserving_mpsc/tests.rs | Reserving MPSC-specific correctness and behavior tests. |
| crates/windows-waitable-queues/src/permit_mpsc.rs | Experimental permit-based MPSC claim protocol (feature-gated). |
| crates/windows-waitable-queues/src/permit_mpsc/tests.rs | Tests for the experimental permit-claim shape. |
Review details
- Files reviewed: 37/39 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The crate is publish = true and was wired into release-please, but not into the workflow that actually publishes: it had no tag trigger, was absent from the workflow_dispatch crate options, and was missing from the workspace_crates allowlist that gates waiting for sibling dependencies on crates.io. A release tag for it would not have published. All three lists are the set of publishable crates -- everything except windows-guard-alloc and windows-platform-probes, which are publish = false -- and now agree with it at 12 entries each. Raised in review on #59. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fixed in 841d009. The finding was correct and the fix is exactly the three sites named. \windows-waitable-queues\ is \publish = true\ and was wired into release-please, but not into the workflow that actually publishes -- so a release tag for it would have done nothing. Worth stating the invariant this restores, because it is checkable rather than a matter of taste: all three lists are the set of publishable crates -- every crate under \crates/\ except \windows-guard-alloc\ and \windows-platform-probes, which are \publish = false. All three now agree with that set at 12 entries each, verified by comparing them against the manifests rather than by eye. That the three can drift from the manifests silently is the underlying weakness here; a check that compares them is worth having, but it belongs in its own change rather than riding along on this one. |
There was a problem hiding this comment.
🔵 Needs a closer look
There is at least one confirmed documentation drift in the newly added crate (spsc module docs still show Consumer::pop returning Option<T> instead of Result<T, TryRecvError>), which should be corrected before approval.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
crates/windows-waitable-queues/src/spsc.rs:29
- The module-level API sketch still shows
Consumer::popreturningOption<T>, but the actual publicConsumer::popnow returnsResult<T, TryRecvError>(and the rest of this crate’s docs/traits reflect that). Leaving the old signature here is misleading for readers trying to understand the current public contract.
- Files reviewed: 38/40 changed files
- Comments generated: 0 new
- Review effort level: Lite
…ld pop Making `pop` return `Result<T, TryRecvError>` updated the trait, the impls and the tests, but left five statements of the old contract behind. Raised in review on #59, which found one of them. The four not reported are the same class and worse in effect: the three per-shape `is_disconnected` doc comments each still told the caller to "check this only after `pop` has returned `None`", which is precisely the manual protocol `TryRecvError` was introduced to remove. Documentation instructing a caller to do by hand what the API now does for them is more misleading than a merely stale signature. The trait's copy of that sentence was rewritten with the change; its three inherent siblings were not -- the same per-shape miss the mutation sweep found in the tests. The reported site is the module-level trait sketch in `spsc`, and it is deliberately **not** updated. It is a historical artefact: the prediction made before the traits existed, kept so the check it made possible -- that `slotwise_mpsc` matched it -- remains re-runnable. Editing it would turn a record of what was predicted into a copy of what was built. What was false is the prose around it, which claimed the traits "kept those signatures". That now says which two moved and which one did not, verified against `traits.rs` rather than recalled. Two sites that look like the same defect are not: `finish` genuinely returns `Option`, and `COMPLETED-CHECKLIST.md` quotes the old wording as history. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fixed in 723aa0d, and the sweep found four more of the same class. The reported site is real. Changing The four not reported are worse in effect. Each shape's inherent The reported site is deliberately not updated, and that is the interesting part. The Two sites that look like the same defect are not, and were left: 344 tests, 12 doctests, clippy clean under |
There was a problem hiding this comment.
🔵 Needs a closer look
Several new documentation files (and public rustdoc) reference checklist documents that are not present in the repository, and the PR description understates the set of modified existing files.
Review details
Suppressed comments (3)
Previously missed (3) — in code that hasn't changed since the last review.
.github/workflows/publish-crate.yml:18
- PR description says no existing file was modified except Cargo.toml/Cargo.lock and the two release-please files, but this PR also updates the publish-crate workflow to include the new crate. Please update the PR description to match the actual set of modified existing files (or explain why this workflow change is intentionally in-scope here).
crates/windows-waitable-queues/design-sessions/DESIGN-SESSION-2026-09-02-claim-protocol-prior-art.md:5 - This design-session doc links to
../../../CHECKLIST-ship-topology-and-queues.md, but that file is not present in the repository, so the link is broken.
crates/windows-waitable-queues/src/lib.rs:328 - Public docs reference
CHECKLIST-io-domains.mdfor the remaining-shapes milestones, but that file does not exist in the repo, so this is a dead reference for crate users reading the docs.
- Files reviewed: 38/40 changed files
- Comments generated: 0 new
- Review effort level: Lite
…not in this repository My earlier pass at this had two holes, and review on #59 found both. It matched only markdown *links* of the form [text](../../CHECKLIST-*.md), so bare prose mentions of the same filenames survived; and it globbed src/*.rs and the crate root, never recursing into design-sessions/. Swept recursively this time, and against every relative link rather than the checklist names alone: twelve more references removed, including a design-session link to a workspace-root file. Every relative link in the crate now resolves, checked by resolving each one rather than by eye. Where a reference queued future work, it now says the question is open without pointing at a document a reader of the published crate cannot open. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
All three fixed -- description updated, and the two dead references in d525733. Both of the latter were my sweep's fault rather than sites I judged and kept, so it is worth saying how it failed. The earlier pass had two holes. It matched only markdown links of the form Swept properly this time, recursively and against every relative link rather than the checklist names alone. That found twelve more, including one the review had not flagged: a design-session link to a workspace-root file. Every relative link in the crate now resolves, verified by resolving each one rather than reading them. Where a reference queued future work, it now says the question is open without pointing at a document a reader of the published crate cannot open. On the description: correct, and it was accurate when written -- the workflow change landed afterwards, from your previous review, and I did not go back and update it. It now lists all five modified files with a reason for each, and states that no existing source file is touched, which is the claim I actually meant. 344 tests, 12 doctests, clippy clean under |
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a large, new lock-free/concurrency-heavy crate and associated Windows wait-handle integration that warrants final human review despite strong test coverage and correct release wiring.
Review details
- Files reviewed: 38/40 changed files
- Comments generated: 0 new
- Review effort level: Lite
PR #59 merged the queues crate and release-please then released it at 0.1.0, so main's copy is the newer one: this branch stopped at the layout work, while the peel branch went on to change `pop`, add `is_full` and `try_iter`, close the gaps a mutation sweep found, and sweep the documentation. Every conflict in that crate is `add/add` -- both branches added it independently -- and every one is resolved to main. Checked rather than assumed: main's tree contains every file this branch had for that crate, plus CHANGELOG.md and the two completed-plan records. **The API change breaks consumers that exist only on this branch.** `pop` returns `Result<T, TryRecvError>` now, so thirteen `pop().is_some()` call sites became `pop().is_ok()` -- twelve in `windows-platform-probes`' queue-contention probe and one in `windows-placement-probe`'s peer-index-cache probe. Neither crate exists on main, so nothing there could have caught this. The release-please manifest keeps main's `0.1.0`, which agrees with the crate manifest the merge brought in. Verified: 344 queue tests with all features plus 12 doctests, 233 in `windows-placement-probe`, 39 in `windows-platform-probes`, and clippy clean across the workspace under `-D warnings`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a new crate,
windows-waitable-queues. 40 files, and all but five are new. Five existing files are modified, every one of them release wiring for a new workspace member:Cargo.tomlCargo.lockrelease-please-config.json.release-please-manifest.json.github/workflows/publish-crate.ymlworkspace_cratesallowlistThe workflow change came from review on this PR: the crate is
publish = trueand was registered with release-please, but a release tag for it would not have published without those three entries. All three lists are the set of publishable crates, and now agree with it at 12 entries each.No existing source file is touched.
This is the second peel off #56, which had grown to 248 files across nine crates and was churning under review.
windows-file-watcherwent first as #57 and merged. This crate has no workspace dependencies at all -- onlywindows-sys-- which is what makes it separable.What it is
A Windows thread usually waits on several things at once: a message arrived, or my I/O completed, or shutdown was signalled. Windows is built for that -- a
HANDLEis the universal waitable currency, and I/O completions, process exits, timers and cancellation events are all handles.A queue is the one thing in that list that is not, because the primitive it sleeps on is private to it.
crossbeam-channelblocks inrecvbut exposes no handle, and itsSelectcomposes only channel operations;crossbeam-queuedoes not block at all. So the thread has to poll one source while blocking on another.These queues make readiness itself a
HANDLE. Nothing is given up for it: every shape can still be polled or blocked on directly, and the kernel object is created lazily, so a consumer that only polls never allocates one.Shapes
spscslotwise_mpscreserving_mpscpermit_mpscTwo things worth a reviewer's attention
The claim-word layout is a caller's choice.
reserving_mpscpacks its claim position beside a reservation count in one word. The obvious 32/32 split gives the reservation half 2^32 -- a ceiling nobody reaches -- and pays for it with the whole of the position's headroom, which is a recurrence after ~37 seconds of sustained maximum-rate pushing.Balanced,EnduringandPerpetualtrade that ceiling for a position lasting up to ~20 years, and a probe measured them indistinguishable: the samelock cmpxchgon the sameu64, differing only in shift constants. The opt-indwcasfeature adds a 128-bitWidelayout; it is the only thing here that costs a third-party dependency, since the standard library has no 128-bit atomic.The default stays
Balancedso no caller's behaviour was silently changed, and it is documented as not the recommended layout.popreturnsResult<T, TryRecvError>, notOption<T>. Compared against the eight most-depended-on Rust queue crates, this crate had nine of seventeen table-stakes capabilities and used the majority spelling for each. Three gaps were closed, and this was the important one:pushalready distinguishedFullfromDisconnectedandrecvalready returnedRecvError::Disconnected, so onlypopcollapsed the two -- and the trait documentation asked callers to pair it withis_disconnectedin a specific order, which is aTryRecvErrorwritten as prose. The ordering is now enforced by construction, and checked only on the empty path so a successful take pays nothing.Also:
is_fullmoved onto theBoundedtrait, andtry_iter/drainbecame inherent.Verification
-D warningsin every feature configuration; rustdoc clean under CI's flags both with and withoutdwcascargo check --workspace --all-targets --all-features --lockedcleancargo mutantssweep: 871 mutants, 23 survivors, all addressed. The largest group was the new API tested on one shape and not the others -- every shape implementspopand theBoundedaccessors separately, so covering one said nothing about the rest. Re-running over the touched files confirms the fixes rather than assuming them; the four survivors that remain are documented equivalent mutants.The 154 timeouts were verified rather than assumed: re-injecting one (
validate_capacity -> Ok(())) fails six tests immediately. It is caught decisively, and was recorded as a timeout only because another test in the same process hung and stopped the harness reporting -- the expected shape in a crate of blocking APIs.Known and disclosed
Under the default layout,
reserving_mpsc's claim position recurs after 2^32 pushes and can lose an item, silently. That is stated in the crate documentation, the README and the module docs, each leading with "on every target, not only 32-bit ones", because the phrase "32-bit position" invites the opposite reading. NamingPerpetualmoves it beyond any real deployment at no measured cost.