Skip to content

Commit 820fd1d

Browse files
authored
Safe DMA transfer API: ownership-based framebuffer locking (#31)
* Make DMA transfer API ownership-based to prevent write-after-submit races The previous `start_dma_transfer(&self, framebuffer: &FrameBuf<...>)` released the borrow immediately on return, leaving the caller free to write to the buffer while DMA was still reading it — a data race the compiler could not catch. The new design follows the embedded-hal ecosystem pattern (stm32f4xx-hal, nrf-hal, Embedonomicon): `start_dma_transfer` takes the framebuffer by value and returns a `DmaTransfer` token. The buffer is locked inside the token until `DmaTransfer::wait` returns it, making concurrent access a compile error. Changes: - New `DmaTransfer` trait with `is_done(&self)` and `wait(self) -> Buffer` - New `TransferError<FB>` carries the buffer back on failure so it is never lost - `DisplayBackend::start_dma_transfer` now takes `FrameBuf` by value and returns `Result<Self::Transfer, TransferError<FB>>` - `wait_for_dma`, `is_dma_ready`, `present`, `present_region` removed from the trait — waiting/polling moves to `DmaTransfer`, presenting stays in `SwapChain` - `SimulatorBackend` gains `CompletedTransfer<FB>` — an immediately-done token - `SwapChain` restructured with a `FrontState<FB, Xfer>` enum: the front buffer is either `Idle(FrameBuf)` or `InFlight(Transfer)`, preventing any access path to the buffer while DMA is active - `TripleSwapChain` follows the same pattern - All call sites (`dma_rendering_demo.rs`, `present()` etc.) are unchanged * Fix CI: add Debug impl for TransferError, fix height() method call in test * Add cargo test to pre-commit hook
1 parent 02f40f6 commit 820fd1d

3 files changed

Lines changed: 592 additions & 413 deletions

File tree

.githooks/pre-commit

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
#!/usr/bin/env bash
2+
# Pre-commit hook: format staged Rust files and run the test suite.
3+
#
4+
# Activation (one-time per clone):
5+
# git config core.hooksPath .githooks
6+
#
7+
# Behaviour:
8+
# 1. Runs `cargo fmt --all` and re-stages any files that were already staged.
9+
# 2. Runs `cargo test` to catch compile errors and failing tests before the
10+
# commit lands. Only triggered when at least one .rs or Cargo.toml file is
11+
# staged — pure doc/asset commits are unaffected.
212
set -euo pipefail
313

414
if ! command -v cargo >/dev/null 2>&1; then
5-
echo "pre-commit: cargo not found, skipping rustfmt." >&2
15+
echo "pre-commit: cargo not found, skipping." >&2
616
exit 0
717
fi
818

919
repo_root="$(git rev-parse --show-toplevel)"
1020
cd "$repo_root"
1121

22+
# Collect staged Rust-related files.
1223
staged_files="$(git diff --cached --name-only --diff-filter=ACMR)"
1324
if [[ -z "$staged_files" ]]; then
1425
exit 0
@@ -31,35 +42,5 @@ cargo fmt --all
3142
echo "pre-commit: staging rustfmt updates"
3243
git add -- "${rust_related[@]}"
3344

34-
#!/bin/sh
35-
# Auto-format staged Rust source with cargo fmt before each commit.
36-
#
37-
# Files already in the index that cargo fmt reformats are re-staged
38-
# automatically so the commit is always formatted without disturbing
39-
# unstaged work in the working tree.
40-
#
41-
# Activation (one-time per clone):
42-
# git config core.hooksPath .githooks
43-
44-
set -e
45-
46-
if ! command -v cargo >/dev/null 2>&1; then
47-
echo "pre-commit: cargo not found, skipping fmt"
48-
exit 0
49-
fi
50-
51-
# Collect staged .rs paths (added, copied, modified, renamed in the index).
52-
staged_rs=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.rs$' || true)
53-
54-
if [ -z "$staged_rs" ]; then
55-
exit 0
56-
fi
57-
58-
echo "pre-commit: cargo fmt --all"
59-
cargo fmt --all
60-
61-
# Re-stage only the files that were already staged so that any unstaged edits
62-
# in the working tree are not accidentally included in this commit.
63-
echo "$staged_rs" | while IFS= read -r f; do
64-
[ -f "$f" ] && git add "$f"
65-
done
45+
echo "pre-commit: running cargo test"
46+
cargo test

0 commit comments

Comments
 (0)