Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/fspy_shm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The public API is defined in [`src/lib.rs`](src/lib.rs).

| API | Contract |
| ----------------- | ---------------------------------------------------------------------------------- |
| `create(size)` | Creates a non-empty mapping and returns its unique owner. |
| `create(size)` | Creates a non-empty, zero-initialized mapping and returns its unique owner. |
| `open(id)` | Opens another view of the mapping identified by `id`. |
| `Shm::id()` | Returns the identifier to send to another process. |
| `Shm::len()` | Returns the mapped size. |
Expand All @@ -19,6 +19,8 @@ The public API is defined in [`src/lib.rs`](src/lib.rs).

`Shm` does not synchronize memory access. The fspy channel combines it with atomic frame headers and a lock file. Senders hold a shared file lock while writing. The receiver takes the exclusive lock before reading, which waits for existing senders and rejects new ones.

Every byte in a mapping returned by `create` is initially zero. `open` exposes the mapping's current contents and does not reinitialize them.

## Ownership semantics

`create` returns the only owner. `open` returns non-owning views.
Expand Down
19 changes: 17 additions & 2 deletions crates/fspy_shm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,23 @@ mod tests {

// Page-aligned on all supported targets.
const SIZE: usize = 64 * 1024;
// Use one byte more than 64 KiB to test multiple pages and a partial last page.
const ZERO_INITIALIZED_SIZE: usize = SIZE + 1;

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn new_mapping_is_zero_initialized_in_all_views() {
let owner = create(ZERO_INITIALIZED_SIZE).unwrap();
let opened = open(owner.id()).unwrap();

assert_zero_initialized(&owner);
assert_zero_initialized(&opened);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn create_and_open_are_shared() {
let owner = create(SIZE).unwrap();
assert_eq!(owner.len(), SIZE);
assert_eq!(owner.as_ptr() as usize % align_of::<usize>(), 0);
// SAFETY: No writes occur while this slice is borrowed.
assert!(unsafe { owner.as_slice() }.iter().all(|byte| *byte == 0));

let opened = open(owner.id()).unwrap();
assert_eq!(opened.id(), owner.id());
Expand Down Expand Up @@ -90,6 +99,12 @@ mod tests {
unsafe { shm.as_ptr().add(index).read() }
}

fn assert_zero_initialized(shm: &Shm) {
assert!(shm.len() >= ZERO_INITIALIZED_SIZE);
// SAFETY: No writes occur while this slice is borrowed.
assert!(unsafe { shm.as_slice() }.iter().all(|byte| *byte == 0));
}

fn write_byte(shm: &Shm, index: usize, value: u8) {
assert!(index < shm.len());
// SAFETY: The index is in bounds and tests synchronize all accesses.
Expand Down
3 changes: 2 additions & 1 deletion crates/fspy_shm/src/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ pub struct Shm {
_service: Option<DropGuard>,
}

/// Creates a sealed memfd mapping of `size` bytes and returns its owner.
/// Creates a zero-initialized sealed memfd mapping of `size` bytes and returns
/// its owner.
///
/// The memfd is handed out to other processes by a broker task spawned onto
/// the ambient tokio runtime. The broker stops on its own when the owner is
Expand Down
4 changes: 2 additions & 2 deletions crates/fspy_shm/src/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub struct Shm {
owner: bool,
}

/// Creates a POSIX shared-memory mapping of `size` bytes and returns its
/// owner.
/// Creates a zero-initialized POSIX shared-memory mapping of `size` bytes and
/// returns its owner.
///
/// # Errors
///
Expand Down
4 changes: 2 additions & 2 deletions crates/fspy_shm/src/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub struct Shm {
backing_file: Option<File>,
}

/// Creates a sparse, temporary file-backed named mapping of `size` bytes and
/// returns its owner.
/// Creates a zero-initialized, sparse, temporary file-backed named mapping of
/// `size` bytes and returns its owner.
///
/// # Errors
///
Expand Down
Loading