Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0facf7e
chore: land the documentation, plans and refactors of the crates that…
Oct 22, 2026
57b4c2c
feat(win-handles-sys): set a handle's flags, compare two handles, clo…
Oct 22, 2026
1102924
feat(win-text-sys): new crate, compare_string_ordinal over CompareStr…
Oct 22, 2026
a30b715
feat(win-debugging-sys): new crate, output_debug_string over OutputDe…
Oct 22, 2026
632ec02
feat(win-etw-sys)!: new crate, a Registration over the Event Tracing …
Oct 22, 2026
516466b
feat(win-sync): an Event's clones share one handle, and the wait-only…
Oct 22, 2026
2821f76
feat(threadpool)!: a wait target may be a SharedHandle, and a wait bu…
Oct 22, 2026
849959c
feat(file-enumeration)!: the doorbell is a shared win-sync-sys Event,…
Oct 22, 2026
1927963
chore: duplicate handles through win-handles-sys in the doorbell, the…
Oct 22, 2026
071647d
feat(file-watcher): hand out the receiver's doorbell as a shared handle
Oct 22, 2026
05cb73a
feat(placement-probe): carry each measurement's raw pass and a stable…
Oct 22, 2026
19dbdf3
feat(platform-probes): make the probes' sampling settable from the co…
Oct 22, 2026
341858e
feat(durable-ioring)!: a typed Key<A> carries a target's access, ever…
Oct 22, 2026
d306b91
feat(win-sync)!: delete try_clone and the conversions into OwnedHandl…
Oct 22, 2026
84333e1
chore: the workspace's CI, tooling, design notes, plans and Win32 Lea…
Oct 22, 2026
791f0c6
chore(sabotage): treat win-handles-sys as an input every sweep shares…
Oct 22, 2026
c6ead7f
docs(durable-ioring): a lock wait is reported when the lock is acquir…
Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
137 changes: 117 additions & 20 deletions .github/copilot-instructions.md

Large diffs are not rendered by default.

111 changes: 105 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,34 @@ jobs:
shell: pwsh
run: ./tools/check-encoding.ps1

# Every COMPLETED-CHECKLIST.md: a blank line above each heading, no heading
# glued onto a line, no open box, and no heading or anchor changed against the
# merge base (root CHECKLIST.md, M34.18). The last needs the base commit, so the
# checkout is full. On a pull request the base is the target branch; on a push
# it is the previous tip, and a push with none (a new branch) skips that rule
# rather than failing on a missing commit.
archives:
name: completed-checklist archives
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Run test-check-archives.ps1
shell: pwsh
run: ./tools/test-check-archives.ps1
- name: Run check-archives.ps1
shell: pwsh
env:
ARCHIVE_BASE: ${{ github.event_name == 'pull_request' && format('origin/{0}', github.base_ref) || github.event.before }}
run: |
if (-not $env:ARCHIVE_BASE -or $env:ARCHIVE_BASE -match '^0+$') {
./tools/check-archives.ps1 -NoHistory
} else {
./tools/check-archives.ps1 -Base $env:ARCHIVE_BASE
}
exit $LASTEXITCODE

# release-please decides which crates are versioned and tagged;
# publish-crate.yml decides which tags publish. Nothing connected the two, so
# a crate could be release-managed and unpublishable at once -- and the
Expand Down Expand Up @@ -314,6 +342,35 @@ jobs:
RUST_BACKTRACE: 1
RUST_LIB_BACKTRACE: 1
run: cargo test -p win-durable-ioring --locked --lib -- --include-ignored raw_volume raw_disk
# The ETW provider wrapper against real trace sessions (WE-D-3): each test starts a session
# that logs to a file, enables a provider in it, and reads the file back. Starting a session
# needs an elevated process or the Performance Log Users group, which the runner's
# administrator account has and a developer's usually does not, so the tests are ignored by
# default. A failure here is a result: if the runner stops being able to start a session, the
# answer is to say so, not to delete the tests.
- name: cargo test (win-etw-sys, trace sessions)
if: ${{ matrix.isolated }}
env:
RUST_BACKTRACE: 1
RUST_LIB_BACKTRACE: 1
run: cargo test -p win-etw-sys --locked --test session -- --include-ignored
# The same, for the provider's sink (DE-D-4): each test starts a session, enables the
# provider in it, reports through the sink and decodes what the session recorded. They share
# the one provider, so they serialize themselves.
- name: cargo test (durable-ioring-events, trace sessions)
if: ${{ matrix.isolated }}
env:
RUST_BACKTRACE: 1
RUST_LIB_BACKTRACE: 1
run: cargo test -p durable-ioring-events --locked --test session -- --include-ignored
# The driver's default sink writes to that provider (DI-12.1.6): an instance built with no sink
# of its own, run against a session that is listening. Ignored by default for the same reason.
- name: cargo test (win-durable-ioring, default sink reaches a trace session)
if: ${{ matrix.isolated }}
env:
RUST_BACKTRACE: 1
RUST_LIB_BACKTRACE: 1
run: cargo test -p win-durable-ioring --locked --lib -- --include-ignored an_instance_with_no_chosen_sink_writes_its_events_to_etw
# windows-file-watcher-example-test-harness is a normal workspace member
# that depends on windows-file-watcher with the test-util feature, so
# the `--workspace` steps above unify that feature onto
Expand Down Expand Up @@ -420,20 +477,44 @@ jobs:
# `#[ignore]`d tests, and the binaries that print the magnitudes.
#
# Every measurement in this workspace was originally taken on ARM64, so
# running them on this x64 runner is what answers "which findings are
# running them on an x64 runner is what answers "which findings are
# architecture-dependent" (CHECKLIST-thread-ambient.md, M27.5).
#
# The ARM64 entry is the other half (windows-platform-probes M2.15). Every
# other job here only BUILDS aarch64, and architecture is the one report
# shape a test corpus cannot vary, because it is fixed at compile time: a
# fixture that hard-codes one architecture passes on that host and no other.
# Only running the suite on a second architecture can see that class. The
# windows-11-arm label is a GitHub-hosted Windows 11 ARM64 runner, free for
# public repositories.
#
# A FAILURE HERE IS A RESULT, NOT A BUILD BREAK TO PATCH AWAY. The ignored
# tests assert the *shape* of a measured platform fact, so a failure means
# the fact differs on this architecture and the design note resting on it
# needs revisiting. Read the output before changing an assertion.
name: platform probes (x64, ignored tier + magnitudes)
runs-on: windows-latest
name: ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
strategy:
# One architecture's result must not cancel the other's: a difference
# between the two is the finding, and it needs both halves.
fail-fast: false
matrix:
include:
- name: platform probes (x64, ignored tier + magnitudes)
runner: windows-latest
- name: platform probes (arm64, ignored tier + magnitudes)
runner: windows-11-arm
# Bounded so a probe that wedges reports rather than burning the job's
# default six-hour ceiling. The suite takes seconds when healthy.
timeout-minutes: 15
env:
RUSTUP_TOOLCHAIN: stable
# The probes' build script stamps these into the binaries (M4.8), so a
# report from this job names the commit it was built from and says it came
# from CI. The commit is what the checkout built: on a pull request, the
# merge commit.
PLATFORM_PROBES_COMMIT: ${{ github.sha }}
PLATFORM_PROBES_SOURCE: ci
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
Expand Down Expand Up @@ -466,6 +547,8 @@ jobs:
# probe-cancel-io is DELIBERATELY ABSENT and must stay that way. It is
# binary-only because CancelSynchronousIo can block indefinitely -- that
# is the finding -- so running it here would hang the job by design.
# (The row census in the test step above does run it, under a deadline,
# reading its row as it is written rather than waiting for it to exit.)
#
# One step per probe, deliberately, rather than one `run: |` block listing
# them. These steps take the Windows runner's default shell, `pwsh`, where
Expand Down Expand Up @@ -533,13 +616,13 @@ jobs:
- name: probe magnitudes (topology)
if: "!cancelled() && steps.build.outcome == 'success'"
run: cargo run -p windows-platform-probes --bin probe-topology --locked
# `--release` on the next two, and ONLY on those two, because they are the
# only probes here that report nanoseconds. Everything above measures
# `--release` on the next four, and ONLY on those four, because they are
# the only probes here that report nanoseconds. Everything above measures
# BEHAVIOUR -- what an API refuses, what a handle reports, which errors
# appear -- and that does not change with the optimisation level, so those
# keep the dev profile and the build time it saves.
#
# These two do not have that luxury. They compare operations a few tens of
# These do not have that luxury. The two cost probes compare operations a few tens of
# nanoseconds apart, and in an unoptimized build the loop, the closure
# indirection, and the request construction around each measured call
# carry overhead that does not shrink uniformly across them. The RATIOS
Expand Down Expand Up @@ -572,6 +655,22 @@ jobs:
- name: probe magnitudes (request cost)
if: "!cancelled() && steps.build.outcome == 'success'"
run: cargo run -p windows-platform-probes --bin probe-request-cost --locked --release
# The two coherence probes, run here so that every build's log carries a
# run of each on BOTH architectures -- this job's arm64 entry is the only
# ARM64 hardware this workspace reaches, and the peer-index probe's finding
# is one that inverts between the two (windows-platform-probes M4.11).
#
# The queue probe is limited to 1, 2 and 4 producers because a hosted
# runner has four processors: rows above that would measure the scheduler
# and report it as contention. Its report says the run was not the
# defaults, and prints the processors it had. The full curve is still run
# by hand on a known machine.
- name: probe magnitudes (queue contention, 1 to 4 producers)
if: "!cancelled() && steps.build.outcome == 'success'"
run: cargo run -p windows-platform-probes --bin probe-queue-contention --locked --release -- --producers 1,2,4
- name: probe magnitudes (peer index cache)
if: "!cancelled() && steps.build.outcome == 'success'"
run: cargo run -p windows-platform-probes --bin probe-peer-index-cache --locked --release
# Both halves of the long-path pair, deliberately. Either alone says
# nothing: the finding is the *difference* between two executables that
# differ only in whether `build.rs` embedded the `longPathAware` manifest,
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/publish-crate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ on:
push:
tags:
- 'durable-ioring-v*'
- 'durable-ioring-events-v*'
- 'io-buffers-v*'
- 'win-authorization-sys-v*'
- 'win-debugging-sys-v*'
- 'win-durable-ioring-v*'
- 'win-error-codes-v*'
- 'win-etw-sys-v*'
- 'win-handles-sys-v*'
- 'win-multi-file-tail-watcher-v*'
- 'win-numa-sys-v*'
- 'win-pipes-sys-v*'
- 'win-shared-os-owned-handle-v*'
- 'win-sync-sys-v*'
- 'win-text-sys-v*'
- 'win-time-sys-v*'
- 'win-volume-sys-v*'
- 'windows-file-enumeration-sys-v*'
Expand Down Expand Up @@ -43,16 +47,20 @@ on:
type: choice
options:
- durable-ioring
- durable-ioring-events
- io-buffers
- win-authorization-sys
- win-debugging-sys
- win-durable-ioring
- win-error-codes
- win-etw-sys
- win-handles-sys
- win-multi-file-tail-watcher
- win-numa-sys
- win-pipes-sys
- win-shared-os-owned-handle
- win-sync-sys
- win-text-sys
- win-time-sys
- win-volume-sys
- windows-file-enumeration-sys
Expand Down Expand Up @@ -135,7 +143,7 @@ jobs:
- name: Wait for workspace-sibling dependencies on crates.io
shell: bash
run: |
workspace_crates="durable-ioring io-buffers win-authorization-sys win-durable-ioring win-error-codes win-handles-sys win-multi-file-tail-watcher win-numa-sys win-pipes-sys win-shared-os-owned-handle win-sync-sys win-time-sys win-volume-sys windows-file-enumeration-sys windows-file-watcher windows-file-watcher-example-test-harness windows-impersonation-token-sys windows-ioring-sys windows-namespace-request-sys windows-overlapped-io-sys windows-thread-ambient-sys windows-threadpool-sys windows-topology-sys windows-waitable-queues wtf-string"
workspace_crates="durable-ioring durable-ioring-events io-buffers win-authorization-sys win-debugging-sys win-durable-ioring win-error-codes win-etw-sys win-handles-sys win-multi-file-tail-watcher win-numa-sys win-pipes-sys win-shared-os-owned-handle win-sync-sys win-text-sys win-time-sys win-volume-sys windows-file-enumeration-sys windows-file-watcher windows-file-watcher-example-test-harness windows-impersonation-token-sys windows-ioring-sys windows-namespace-request-sys windows-overlapped-io-sys windows-thread-ambient-sys windows-threadpool-sys windows-topology-sys windows-waitable-queues wtf-string"
metadata="$(cargo metadata --no-deps --format-version 1)"
# `tr -d '\r'` is load-bearing on the Windows runner: jq.exe writes
# CRLF, and `read` splits on LF alone, so without this the last field
Expand Down
4 changes: 4 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"crates/win-handles-sys": "0.1.0",
"crates/win-durable-ioring": "0.3.2",
"crates/win-sync-sys": "0.0.2",
"crates/win-text-sys": "0.0.1",
"crates/win-debugging-sys": "0.0.1",
"crates/win-etw-sys": "0.0.1",
"crates/durable-ioring-events": "0.0.1",
"crates/win-time-sys": "0.1.0",
"crates/win-multi-file-tail-watcher": "0.2.0",
"crates/win-volume-sys": "0.1.1",
Expand Down
22 changes: 2 additions & 20 deletions CHECKLIST-thread-ambient.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Authoritative decisions are in [DESIGN-NOTES.md](DESIGN-NOTES.md) and, for the f
parked no longer: every `M26+` item was gated on the namespace-facility design branch reaching
`main`, and both [crates/windows-namespace-request-sys](crates/windows-namespace-request-sys) and
[crates/windows-thread-ambient-sys](crates/windows-thread-ambient-sys) are on `main` now, so the
gate has lifted and the three items are pending. They keep the `M26+` id until someone graduates
gate has lifted and the items still unchecked are pending. They keep the `M26+` id until someone graduates
them to a number, which `M34.7` in [CHECKLIST.md](CHECKLIST.md) owns.

## M26+ -- Was gated on the namespace-facility design branch landing; that gate has lifted
Expand All @@ -40,22 +40,4 @@ them to a number, which `M34.7` in [CHECKLIST.md](CHECKLIST.md) owns.
measured trap in the same edit: an invalid bit fails the whole `SetThreadErrorMode` call, so a
forced-plus-transplanted combination installs nothing if the transplanted part is invalid.

- [ ] **M26+.3** -- Make the merge-or-delete decision on the duplicated path preparation. M24.4 copied
`windows-file-enumeration-sys`'s `path.rs` into `windows-namespace-request-sys` rather than depending on
it, because that crate is released and this one was not, and this branch exists to reach publication with
minimal impact on what already ships. **The de-duplication happens after this branch merges with `main`**,
which is what gates this item -- not a release of the new crate. Decide then: either make the enumeration
crate consume it and delete the older copy, or keep both and record what makes them genuinely separate. Do **not** let the duplication become permanent by nobody circling back -- that is
the failure mode the duplicate-then-decide procedure exists to prevent, and it is why this item is here
rather than only in a design note. Until it is settled, a fix to either copy must be applied to both.
See [crates/windows-namespace-request-sys/DESIGN-NOTES.md](crates/windows-namespace-request-sys/DESIGN-NOTES.md)
-> `D-9`.

**Decided 2026-10-15, at the engineer's request: the enumeration crate consumes the request crate's
path contract and deletes its older copy.** The branch has merged with `main`, which was the gate.
The work is `PATH-1` in [crates/windows-file-enumeration-sys/CHECKLIST.md](crates/windows-file-enumeration-sys/CHECKLIST.md),
after the request crate's `NR-3.3` to `NR-3.6`
([CHECKLIST.md](crates/windows-namespace-request-sys/CHECKLIST.md)); this item is done when `PATH-1`
is. The request crate's path contract is itself replaced by
[D-19](crates/windows-namespace-request-sys/DESIGN-NOTES.md#d-19), so what the enumeration crate
consumes is that one, not the copy that was made.
- [x] **M26+.3** -- The duplicated path preparation is merged: `windows-file-enumeration-sys` consumes the request crate's `AnchoredPath` and its older copy is deleted. -> [completed 2026-10-18](COMPLETED-CHECKLIST.md#m263)
Loading
Loading