Skip to content

Fix GPIO wait lifetimes and stabilize BMP3xx timing tests - #2630

Open
krwq with Copilot wants to merge 7 commits into
mainfrom
copilot/fix-cancellation-blocked-worker
Open

krwq with Copilot wants to merge 7 commits into
mainfrom
copilot/fix-cancellation-blocked-worker

Conversation

Copilot AI commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to krwq's request, addressing the blocked V2 cleanup worker and premature asynchronous cleanup.

  • Complete single-event callback removal and wait-handle disposal before returning, without a detached cleanup task. Dispatch user callbacks outside the subscription lock and synchronize signaling with disposal to avoid cancellation-and-join deadlocks and late-callback races.
  • Use the base asynchronous wrapper around the Raspberry Pi synchronous wait, retaining pin ownership and the linked cancellation-token source until completion.
  • Stabilize the BMP3xx simulator tests that were intermittently failing macOS CI. Three timing-window tests now use FakeTimeProvider instead of real-time scheduling; the oversampling regression checks rejection at 20 ms and acceptance at 68 ms. The simulator defaults to system time, and BMP3xx production code is unchanged.

Validation on Windows with the actual .NET 8/xUnit runner: all 89 BMP3xx tests passed in both Debug and Release; all four Windows-supported GPIO lifetime cases passed in both configurations using the repository's existing platform filter. The reviewed timing repair also passed 50 repeated simulator-suite runs (450 test executions) and a controlled real 100 ms scheduling delay. All eight GPIO lifetime cases also passed on Ubuntu with the actual .NET 8/xUnit runner in both Debug and Release, including all four Unix-only Raspberry Pi cases. No hardware testing is claimed.

All six Debug/Release matrix jobs across Linux, macOS, and Windows passed in cross-platform CI on the combined commit 39d244de0b230d211c67f874bd5db7d91c883c7d.

Concurrent-wait reference counting, callback removal by event type, and EdgeEvent disposal remain outside this change.

Timothy-Lee-Grant and others added 2 commits October 22, 2026 18:04
…ensor) (#2627)

* Creating Bmp3xx scaffold

* Add Bmp3xx register map and settings enums

* Add BMP3xx calibration parsing and compensation with tests

* Add Bmp390/Bmp388 device classes with simulated-device tests

* Added README and sample

* Report pressure as unavailable when the temperature is out of range

* Add calibration test vectors from a real BMP390

* Wait for the running measurement when leaving normal or forced mode

* Document the wait when leaving normal or forced mode

* Clear stale data-ready flags before a forced measurement

* Wait for the longest conversion that can still be running

* Track whether a measurement exists instead of a reset-value sentinel

* Document that Read discards unread data and needs no forced mode first
Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
@dotnet-policy-service dotnet-policy-service Bot added area-System.Device.Gpio Contains types for using general-purpose I/O (GPIO) pins labels Oct 22, 2026
Copilot AI and others added 2 commits October 22, 2026 16:09
Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
…ynchronously

Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix cancellation issues in V2 cleanup worker and ValueTask Fix GPIO single-event cleanup and Raspberry Pi async wait lifetimes Oct 22, 2026
Copilot AI requested a review from krwq October 22, 2026 16:15
@krwq

krwq commented Oct 22, 2026

Copy link
Copy Markdown
Member

/azp run dotnet.iot

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@krwq

krwq commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

@copilot Please fix a cancellation deadlock introduced by this PR and update this same PR. In LibGpiodV2EventObserver, the wait's finally now acquires _handlersBySubscription before the wait task completes (lines 47–57). HandleEdgeEvent holds that same lock while invoking user callbacks (lines 246–272). Concrete scenario using LibGpiodV2Driver directly: register an ordinary callback on one offset, start a single asynchronous wait on a DIFFERENT offset, and have the callback cancel that wait and synchronously join its task. The subscription-registry lock is shared across offsets, so this does not require concurrent operations on the same pin. The callback waits for the task; the task's cleanup waits for the callback-held lock. Neither can complete. This is introduced by the new synchronous cleanup, not the separate reference-counting finding. Preserve deterministic cleanup before wait completion without invoking arbitrary user callbacks under the subscription-registry lock. Make callback dispatch versus wait-handle removal/disposal safe as well: merely moving callback invocation outside the lock can otherwise invoke an already-disposed wait handle. Do not restore a detached cleanup task to hide the deadlock. Add a bounded, hardware-independent cancellation-and-join regression and coverage of callback dispatch racing with wait cleanup. Run the targeted GPIO tests and an independent fresh-reader review before finalizing. Commit the correction to this PR's existing branch; do not open another PR or force-push. Keep the independently merged BMP3xx timing failure separate; its local repair is already being investigated. The unrelated callback reference-counting/event-type-removal and EdgeEvent-disposal changes remain outside this PR.

…aling

Co-authored-by: krwq <660048+krwq@users.noreply.github.com>

Copilot AI commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please fix a cancellation deadlock introduced by this PR and update this same PR. In LibGpiodV2EventObserver, the wait's finally now acquires _handlersBySubscription before the wait ta...

Fixed in adc11cc on this branch. Callback snapshots are dispatched outside the registry lock; wait-handle signaling and disposal are synchronized so captured callbacks are safe after cleanup. Added bounded, repeated cancellation-and-join and dispatch/cleanup regressions. Fresh independent review found no significant issues. GPIO build and targeted tests were attempted but blocked before compilation by Arcade feed DNS failure; CodeQL timed out. BMP3xx and the other excluded changes remain untouched.

Preserve the existing GPIO PR history and main's BMP3xx baseline. Use controllable time for the simulator's measurement-window assertions while retaining the system clock for driver tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 4a6f4935-0e14-465b-9dc0-434376c5f6f5
@dotnet-policy-service dotnet-policy-service Bot added the area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio label Oct 23, 2026
@krwq krwq changed the title Fix GPIO single-event cleanup and Raspberry Pi async wait lifetimes Fix GPIO wait lifetimes and stabilize BMP3xx timing tests Oct 23, 2026
@krwq
krwq marked this pull request as ready for review October 23, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-device-bindings Device Bindings for audio, sensor, motor, and display hardware that can used with System.Device.Gpio area-System.Device.Gpio Contains types for using general-purpose I/O (GPIO) pins

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants