Skip to content

Add windows-waitable-queues, bounded queues waitable as a HANDLE - #59

Merged
MikeGrier merged 10 commits into
mainfrom
mikegrier/waitable-queues
Sep 5, 2026
Merged

Add windows-waitable-queues, bounded queues waitable as a HANDLE#59
MikeGrier merged 10 commits into
mainfrom
mikegrier/waitable-queues

Conversation

@MikeGrier

@MikeGrier MikeGrier commented Sep 5, 2026

Copy link
Copy Markdown
Owner

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:

File Why
Cargo.toml adds the workspace member
Cargo.lock locks the new package
release-please-config.json registers the package
.release-please-manifest.json tracks its version
.github/workflows/publish-crate.yml tag trigger, dispatch option, and the workspace_crates allowlist

The workflow change came from review on this PR: the crate is publish = true and 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-watcher went first as #57 and merged. This crate has no workspace dependencies at all -- only windows-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 HANDLE is 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-channel blocks in recv but exposes no handle, and its Select composes only channel operations; crossbeam-queue does 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

Shape Producers Adds
spsc one nothing -- no compare-and-swap on either side
slotwise_mpsc many Vyukov's per-slot sequence protocol
reserving_mpsc many claiming a slot before the message exists
permit_mpsc many experimental claim protocol, non-default feature, outside the semver promise

Two things worth a reviewer's attention

The claim-word layout is a caller's choice. reserving_mpsc packs 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, Enduring and Perpetual trade that ceiling for a position lasting up to ~20 years, and a probe measured them indistinguishable: the same lock cmpxchg on the same u64, differing only in shift constants. The opt-in dwcas feature adds a 128-bit Wide layout; it is the only thing here that costs a third-party dependency, since the standard library has no 128-bit atomic.

The default stays Balanced so no caller's behaviour was silently changed, and it is documented as not the recommended layout.

pop returns Result<T, TryRecvError>, not Option<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: push already distinguished Full from Disconnected and recv already returned RecvError::Disconnected, so only pop collapsed the two -- and the trait documentation asked callers to pair it with is_disconnected in a specific order, which is a TryRecvError written as prose. The ordering is now enforced by construction, and checked only on the empty path so a successful take pays nothing.

Also: is_full moved onto the Bounded trait, and try_iter/drain became inherent.

Verification

  • 344 tests with all features, 304 by default, 12 doctests -- the README is compiled, so an example cannot rot into teaching a name that no longer exists
  • Clippy clean under -D warnings in every feature configuration; rustdoc clean under CI's flags both with and without dwcas
  • cargo check --workspace --all-targets --all-features --locked clean
  • A full cargo mutants sweep: 871 mutants, 23 survivors, all addressed. The largest group was the new API tested on one shape and not the others -- every shape implements pop and the Bounded accessors 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. Naming Perpetual moves it beyond any real deployment at no measured cost.

Mike Grier and others added 7 commits September 5, 2026 00:39
…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>
Copilot AI lite review requested due to automatic review settings September 5, 2026 10:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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-queues crate (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.

Comment thread release-please-config.json
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>
Copilot AI review requested due to automatic review settings September 5, 2026 10:48
@MikeGrier

Copy link
Copy Markdown
Owner Author

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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::pop returning Option<T>, but the actual public Consumer::pop now returns Result<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>
Copilot AI review requested due to automatic review settings September 5, 2026 10:59
@MikeGrier

Copy link
Copy Markdown
Owner Author

Fixed in 723aa0d, and the sweep found four more of the same class.

The reported site is real. Changing pop to return Result<T, TryRecvError> updated the trait, the impls and the tests, and left five statements of the old contract behind.

The four not reported are worse in effect. Each shape's inherent is_disconnected doc still said "check this only after pop has returned None" -- which is exactly the manual protocol TryRecvError was introduced to remove. Documentation telling a caller to do by hand what the API now does for them is more misleading than a stale signature. The trait's copy of that sentence was rewritten with the change; its three inherent siblings were not, which is the same per-shape miss a mutation sweep found in the tests earlier on this branch.

The reported site is deliberately not updated, and that is the interesting part. The spsc module sketch is a historical artefact -- the prediction written before the traits existed, kept so the check it made possible (that slotwise_mpsc matched it) stays re-runnable. Editing it would turn a record of what was predicted into a copy of what was built, destroying its only value. What was actually false is the prose around it, which claimed the traits "kept those signatures". That now names which two moved (Consumer::pop's return, and Bounded gaining remaining/is_full) and which one did not (Producer), checked against traits.rs rather than recalled -- my first draft of that list was itself incomplete, omitting drain/try_iter.

Two sites that look like the same defect are not, and were left: finish genuinely returns Option, and COMPLETED-CHECKLIST.md quotes the old wording as history.

344 tests, 12 doctests, clippy clean under -D warnings, rustdoc clean under CI's flags with and without dwcas.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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.md for 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>
Copilot AI review requested due to automatic review settings September 5, 2026 13:14
@MikeGrier

Copy link
Copy Markdown
Owner Author

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 [text](../../CHECKLIST-*.md), so bare prose mentions of the same filenames survived untouched -- and it globbed src/*.rs and the crate root, never recursing into design-sessions/. Those are exactly the two sites reported.

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 -D warnings, rustdoc clean under CI's flags with and without dwcas, encoding check clean.

@MikeGrier
MikeGrier merged commit 2deecb4 into main Sep 5, 2026
21 checks passed
@MikeGrier
MikeGrier deleted the mikegrier/waitable-queues branch September 5, 2026 13:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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

MikeGrier pushed a commit that referenced this pull request Sep 5, 2026
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>
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