From 4e0e7492c9e882779a1ebf12d95d36d6577419a3 Mon Sep 17 00:00:00 2001 From: wan9chi Date: Thu, 9 Jul 2026 10:53:41 +0800 Subject: [PATCH 1/8] docs(fspy): document shared-memory facade ownership semantics Document the cross-platform create/open contract of the fspy_shm facade: owner lifetime gates new opens, already-open views survive owner teardown, and Windows may keep the name resolvable while other handles hold the section object alive. Co-Authored-By: Claude Fable 5 --- crates/fspy_shm/src/lib.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/fspy_shm/src/lib.rs b/crates/fspy_shm/src/lib.rs index 0f1cea31..4b440ca1 100644 --- a/crates/fspy_shm/src/lib.rs +++ b/crates/fspy_shm/src/lib.rs @@ -1,4 +1,23 @@ //! Behavior-neutral shared-memory facade for fspy channels. +//! +//! # Ownership semantics +//! +//! [`create`] returns the mapping's unique owner; [`open`] attaches an +//! additional view of an existing mapping. All platform implementations +//! uphold the same contract: +//! +//! - While the owner is alive, [`open`] succeeds for any process that knows +//! the mapping's id. +//! - Already-open views remain fully usable after the owner is dropped and +//! keep the underlying memory alive for their own lifetime. +//! - Once the owner is dropped, new [`open`] calls are no longer guaranteed +//! to succeed: they fail on POSIX platforms (the name is unlinked), while +//! on Windows they may still succeed as long as other handles or views keep +//! the underlying section object alive. +//! +//! The fspy channel additionally gates sender creation with the receiver's +//! lock file, so the platform difference in the last point is not observable +//! in-protocol. use std::io; @@ -9,7 +28,11 @@ pub struct Shm { inner: Shmem, } -/// Creates a shared-memory mapping of `size` bytes. +/// Creates a shared-memory mapping of `size` bytes and returns its owner. +/// +/// Dropping the returned owner stops new [`open`] calls from being guaranteed +/// to succeed, while views that are already open stay usable (see the +/// [ownership semantics](crate)). /// /// # Errors /// @@ -23,7 +46,11 @@ pub fn create(size: usize) -> io::Result { Ok(Shm { inner }) } -/// Opens the shared-memory mapping identified by `id`. +/// Opens a view of the shared-memory mapping identified by `id`. +/// +/// Guaranteed to succeed only while the mapping's owner is alive; the +/// returned view stays usable independently of the owner afterwards (see the +/// [ownership semantics](crate)). /// /// # Errors /// From 1981c351241034fdc341c9bb1902c531b251147e Mon Sep 17 00:00:00 2001 From: wan9chi Date: Fri, 10 Jul 2026 22:27:37 +0800 Subject: [PATCH 2/8] docs(fspy): describe shared memory API semantics Co-authored-by: GPT-5 Codex --- crates/fspy_shm/README.md | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 crates/fspy_shm/README.md diff --git a/crates/fspy_shm/README.md b/crates/fspy_shm/README.md new file mode 100644 index 00000000..cf33cbfd --- /dev/null +++ b/crates/fspy_shm/README.md @@ -0,0 +1,53 @@ +# fspy_shm + +`fspy_shm` is the private shared-memory layer used by fspy IPC channels. It +gives the channel one API for creating a mapping, passing its identifier to +another process, and opening additional views of the same bytes. + +The crate is an implementation boundary, not a general-purpose shared-memory +library. Callers must not interpret an identifier or depend on a platform's +native naming scheme. + +## API + +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. | +| `open(id, size)` | Opens another view of the mapping identified by `id`. Callers pass the same logical size used at creation. | +| `Shm::id()` | Returns the opaque identifier that can be serialized to another process. | +| `Shm::len()` | Returns the logical length exposed to the channel. | +| `Shm::as_ptr()` | Returns a mutable raw pointer to the first exposed byte. | +| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | + +`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. + +## Ownership semantics + +`create` returns the only owner. `open` returns non-owning views. + +- While the owner is alive, a process that knows the identifier can open the + mapping. +- An opened view remains usable after the owner is dropped. Its operating + system mapping keeps the underlying bytes alive. +- After the owner is dropped, a new `open` is not portable. POSIX removes the + name, while Windows can keep a named section discoverable until its final + handle or view is closed. + +The channel closes that Windows difference with its lock-file protocol. +[`ChannelConf::sender`](../fspy_shared/src/ipc/channel/mod.rs) opens and locks +the receiver's exact lock-file path before it calls `fspy_shm::open`. The +receiver removes that path before dropping the mapping owner, so a sender that +starts later fails before opening shared memory. + +## Backend boundary + +At this point in the stack, `fspy_shm` delegates mapping creation and opening +to the [`shared_memory`](https://crates.io/crates/shared_memory) crate. The +facade deliberately exposes only the behavior needed by fspy so each platform +can later choose a different implementation without changing the channel +protocol. From 7da9688cb0bb39fbdd42829b58deb4818c8b3789 Mon Sep 17 00:00:00 2001 From: wan9chi Date: Fri, 10 Jul 2026 23:44:00 +0800 Subject: [PATCH 3/8] docs(fspy): simplify shared memory API wording Co-authored-by: GPT-5 Codex --- crates/fspy_shm/README.md | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/crates/fspy_shm/README.md b/crates/fspy_shm/README.md index cf33cbfd..f7d341a4 100644 --- a/crates/fspy_shm/README.md +++ b/crates/fspy_shm/README.md @@ -4,22 +4,21 @@ gives the channel one API for creating a mapping, passing its identifier to another process, and opening additional views of the same bytes. -The crate is an implementation boundary, not a general-purpose shared-memory -library. Callers must not interpret an identifier or depend on a platform's -native naming scheme. +`fspy_shm` exposes only the operations used by fspy. Callers must treat an +identifier as a string and must not depend on a platform's naming scheme. ## API 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. | -| `open(id, size)` | Opens another view of the mapping identified by `id`. Callers pass the same logical size used at creation. | -| `Shm::id()` | Returns the opaque identifier that can be serialized to another process. | -| `Shm::len()` | Returns the logical length exposed to the channel. | -| `Shm::as_ptr()` | Returns a mutable raw pointer to the first exposed byte. | -| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | +| API | Contract | +| ----------------- | --------------------------------------------------------------------------------------------- | +| `create(size)` | Creates a non-empty mapping and returns its unique owner. | +| `open(id, size)` | Opens another view of the mapping identified by `id`. Callers pass the size used at creation. | +| `Shm::id()` | Returns the identifier to send to another process. | +| `Shm::len()` | Returns the mapped size. | +| `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. | +| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | `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 @@ -34,20 +33,19 @@ existing senders and rejects new ones. mapping. - An opened view remains usable after the owner is dropped. Its operating system mapping keeps the underlying bytes alive. -- After the owner is dropped, a new `open` is not portable. POSIX removes the - name, while Windows can keep a named section discoverable until its final - handle or view is closed. +- After the owner is dropped, new opens behave differently by platform. POSIX + removes the name. Windows can continue accepting opens by section name until + the final handle or view is closed. -The channel closes that Windows difference with its lock-file protocol. +The channel hides that difference with its lock file. [`ChannelConf::sender`](../fspy_shared/src/ipc/channel/mod.rs) opens and locks the receiver's exact lock-file path before it calls `fspy_shm::open`. The -receiver removes that path before dropping the mapping owner, so a sender that +receiver removes that path before dropping the owner, so a sender that starts later fails before opening shared memory. ## Backend boundary At this point in the stack, `fspy_shm` delegates mapping creation and opening -to the [`shared_memory`](https://crates.io/crates/shared_memory) crate. The -facade deliberately exposes only the behavior needed by fspy so each platform -can later choose a different implementation without changing the channel -protocol. +to the [`shared_memory`](https://crates.io/crates/shared_memory) crate. Because +callers use only the API above, later changes can replace the backend on each +platform without changing the channel protocol. From d9a54d028c3c8489215e31beef3fecd9c98e1aa3 Mon Sep 17 00:00:00 2001 From: wan9chi Date: Fri, 10 Jul 2026 23:52:59 +0800 Subject: [PATCH 4/8] docs(fspy): remove hard wraps from shared memory README Co-authored-by: GPT-5 Codex --- crates/fspy_shm/README.md | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/crates/fspy_shm/README.md b/crates/fspy_shm/README.md index f7d341a4..7eef4485 100644 --- a/crates/fspy_shm/README.md +++ b/crates/fspy_shm/README.md @@ -1,11 +1,8 @@ # fspy_shm -`fspy_shm` is the private shared-memory layer used by fspy IPC channels. It -gives the channel one API for creating a mapping, passing its identifier to -another process, and opening additional views of the same bytes. +`fspy_shm` is the private shared-memory layer used by fspy IPC channels. It gives the channel one API for creating a mapping, passing its identifier to another process, and opening additional views of the same bytes. -`fspy_shm` exposes only the operations used by fspy. Callers must treat an -identifier as a string and must not depend on a platform's naming scheme. +`fspy_shm` exposes only the operations used by fspy. Callers must treat an identifier as a string and must not depend on a platform's naming scheme. ## API @@ -20,32 +17,18 @@ The public API is defined in [`src/lib.rs`](src/lib.rs). | `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. | | `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | -`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. +`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. ## Ownership semantics `create` returns the only owner. `open` returns non-owning views. -- While the owner is alive, a process that knows the identifier can open the - mapping. -- An opened view remains usable after the owner is dropped. Its operating - system mapping keeps the underlying bytes alive. -- After the owner is dropped, new opens behave differently by platform. POSIX - removes the name. Windows can continue accepting opens by section name until - the final handle or view is closed. +- While the owner is alive, a process that knows the identifier can open the mapping. +- An opened view remains usable after the owner is dropped. Its operating system mapping keeps the underlying bytes alive. +- After the owner is dropped, new opens behave differently by platform. POSIX removes the name. Windows can continue accepting opens by section name until the final handle or view is closed. -The channel hides that difference with its lock file. -[`ChannelConf::sender`](../fspy_shared/src/ipc/channel/mod.rs) opens and locks -the receiver's exact lock-file path before it calls `fspy_shm::open`. The -receiver removes that path before dropping the owner, so a sender that -starts later fails before opening shared memory. +The channel hides that difference with its lock file. [`ChannelConf::sender`](../fspy_shared/src/ipc/channel/mod.rs) opens and locks the receiver's exact lock-file path before it calls `fspy_shm::open`. The receiver removes that path before dropping the owner, so a sender that starts later fails before opening shared memory. ## Backend boundary -At this point in the stack, `fspy_shm` delegates mapping creation and opening -to the [`shared_memory`](https://crates.io/crates/shared_memory) crate. Because -callers use only the API above, later changes can replace the backend on each -platform without changing the channel protocol. +At this point in the stack, `fspy_shm` delegates mapping creation and opening to the [`shared_memory`](https://crates.io/crates/shared_memory) crate. Because callers use only the API above, later changes can replace the backend on each platform without changing the channel protocol. From 866b745c01237eed4ef4813d8715be8c2471f33b Mon Sep 17 00:00:00 2001 From: wan9chi Date: Sat, 11 Jul 2026 06:37:36 +0800 Subject: [PATCH 5/8] docs(fspy): use README for crate documentation Co-authored-by: GPT-5 Codex --- crates/fspy_shm/src/lib.rs | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/crates/fspy_shm/src/lib.rs b/crates/fspy_shm/src/lib.rs index 4b440ca1..0c2657c0 100644 --- a/crates/fspy_shm/src/lib.rs +++ b/crates/fspy_shm/src/lib.rs @@ -1,23 +1,4 @@ -//! Behavior-neutral shared-memory facade for fspy channels. -//! -//! # Ownership semantics -//! -//! [`create`] returns the mapping's unique owner; [`open`] attaches an -//! additional view of an existing mapping. All platform implementations -//! uphold the same contract: -//! -//! - While the owner is alive, [`open`] succeeds for any process that knows -//! the mapping's id. -//! - Already-open views remain fully usable after the owner is dropped and -//! keep the underlying memory alive for their own lifetime. -//! - Once the owner is dropped, new [`open`] calls are no longer guaranteed -//! to succeed: they fail on POSIX platforms (the name is unlinked), while -//! on Windows they may still succeed as long as other handles or views keep -//! the underlying section object alive. -//! -//! The fspy channel additionally gates sender creation with the receiver's -//! lock file, so the platform difference in the last point is not observable -//! in-protocol. +#![doc = include_str!("../README.md")] use std::io; From 0b00f624c3d1f2591b5b42f5743cf93eb1e2a34b Mon Sep 17 00:00:00 2001 From: wan9chi Date: Sat, 11 Jul 2026 06:48:22 +0800 Subject: [PATCH 6/8] refactor(fspy): derive shared memory size when opening Co-authored-by: GPT-5 Codex --- crates/fspy_shared/src/ipc/channel/mod.rs | 10 +++------- crates/fspy_shared/src/ipc/channel/shm_io.rs | 2 +- crates/fspy_shm/README.md | 16 ++++++++-------- crates/fspy_shm/src/lib.rs | 14 +++++++------- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/crates/fspy_shared/src/ipc/channel/mod.rs b/crates/fspy_shared/src/ipc/channel/mod.rs index fe352ee1..24031136 100644 --- a/crates/fspy_shared/src/ipc/channel/mod.rs +++ b/crates/fspy_shared/src/ipc/channel/mod.rs @@ -51,7 +51,6 @@ pub struct ChannelConf { lock_file_path: Box, #[wincode(with = "ArcStrSchema")] shm_id: Arc, - shm_size: usize, } /// Creates a mpsc IPC channel with one receiver and a `ChannelConf` that can be passed around processes and used to create multiple senders @@ -65,11 +64,8 @@ pub fn channel(capacity: usize) -> io::Result<(ChannelConf, Receiver)> { let shm = fspy_shm::create(capacity)?; - let conf = ChannelConf { - lock_file_path: lock_file_path.as_os_str().into(), - shm_id: shm.id().into(), - shm_size: capacity, - }; + let conf = + ChannelConf { lock_file_path: lock_file_path.as_os_str().into(), shm_id: shm.id().into() }; let receiver = Receiver::new(lock_file_path, shm)?; Ok((conf, receiver)) @@ -87,7 +83,7 @@ impl ChannelConf { let lock_file = File::open(self.lock_file_path.to_cow_os_str())?; lock_file.try_lock_shared()?; - let shm = fspy_shm::open(&self.shm_id, self.shm_size)?; + let shm = fspy_shm::open(&self.shm_id)?; // SAFETY: `shm` is a freshly opened shared memory region with valid pointer and size. // Exclusive write access is ensured by the shared file lock held by this sender. let writer = unsafe { ShmWriter::new(shm) }; diff --git a/crates/fspy_shared/src/ipc/channel/shm_io.rs b/crates/fspy_shared/src/ipc/channel/shm_io.rs index dd3ce583..537a42a5 100644 --- a/crates/fspy_shared/src/ipc/channel/shm_io.rs +++ b/crates/fspy_shared/src/ipc/channel/shm_io.rs @@ -680,7 +680,7 @@ mod tests { let cmd = command_for_fn!( (shm_name.clone(), child_index), |(shm_name, child_index): (String, usize)| { - let shm = fspy_shm::open(&shm_name, SHM_SIZE).unwrap(); + let shm = fspy_shm::open(&shm_name).unwrap(); // SAFETY: `shm` is a freshly opened shared memory region with a valid // pointer and size. Concurrent write access is safe because `ShmWriter` // uses atomic operations. diff --git a/crates/fspy_shm/README.md b/crates/fspy_shm/README.md index 7eef4485..cee9546b 100644 --- a/crates/fspy_shm/README.md +++ b/crates/fspy_shm/README.md @@ -8,14 +8,14 @@ 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. | -| `open(id, size)` | Opens another view of the mapping identified by `id`. Callers pass the size used at creation. | -| `Shm::id()` | Returns the identifier to send to another process. | -| `Shm::len()` | Returns the mapped size. | -| `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. | -| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | +| API | Contract | +| ----------------- | --------------------------------------------------------------------------------------- | +| `create(size)` | Creates a non-empty mapping and returns its unique owner. | +| `open(id)` | Opens another view and derives its size from the operating-system mapping. | +| `Shm::id()` | Returns the identifier to send to another process. | +| `Shm::len()` | Returns the mapped size. | +| `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. | +| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | `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. diff --git a/crates/fspy_shm/src/lib.rs b/crates/fspy_shm/src/lib.rs index 0c2657c0..b684719a 100644 --- a/crates/fspy_shm/src/lib.rs +++ b/crates/fspy_shm/src/lib.rs @@ -36,8 +36,8 @@ pub fn create(size: usize) -> io::Result { /// # Errors /// /// Returns an error if the mapping does not exist or cannot be mapped. -pub fn open(id: &str, size: usize) -> io::Result { - let conf = ShmemConf::new().size(size).os_id(id); +pub fn open(id: &str) -> io::Result { + let conf = ShmemConf::new().os_id(id); #[cfg(target_os = "windows")] let conf = conf.allow_raw(true); @@ -97,7 +97,7 @@ mod tests { // SAFETY: No writes occur while this slice is borrowed. assert!(unsafe { owner.as_slice() }.iter().all(|byte| *byte == 0)); - let opened = open(owner.id(), SIZE).unwrap(); + let opened = open(owner.id()).unwrap(); assert_eq!(opened.id(), owner.id()); assert_eq!(opened.len(), SIZE); @@ -113,7 +113,7 @@ mod tests { write_byte(&owner, 0, 17); let command = command_for_fn!(owner.id().to_owned(), |id: String| { - let opened = open(&id, SIZE).unwrap(); + let opened = open(&id).unwrap(); assert_eq!(read_byte(&opened, 0), 17); write_byte(&opened, SIZE - 1, 29); }); @@ -127,20 +127,20 @@ mod tests { let id = owner.id().to_owned(); drop(owner); - assert!(open(&id, SIZE).is_err()); + assert!(open(&id).is_err()); } #[test] fn opened_mapping_survives_owner_drop() { let owner = create(SIZE).unwrap(); let id = owner.id().to_owned(); - let opened = open(&id, SIZE).unwrap(); + let opened = open(&id).unwrap(); write_byte(&owner, 0, 17); drop(owner); // Windows keeps the named object alive while an opened view exists. #[cfg(not(target_os = "windows"))] - assert!(open(&id, SIZE).is_err()); + assert!(open(&id).is_err()); assert_eq!(read_byte(&opened, 0), 17); write_byte(&opened, SIZE - 1, 29); assert_eq!(read_byte(&opened, SIZE - 1), 29); From 61f72d86aa08e98b800e4ad5afbc5c42f8897727 Mon Sep 17 00:00:00 2001 From: wan9chi Date: Sat, 11 Jul 2026 06:50:49 +0800 Subject: [PATCH 7/8] docs(fspy): format crate name in README heading Co-authored-by: GPT-5 Codex --- crates/fspy_shm/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/fspy_shm/README.md b/crates/fspy_shm/README.md index cee9546b..eaddfa76 100644 --- a/crates/fspy_shm/README.md +++ b/crates/fspy_shm/README.md @@ -1,4 +1,4 @@ -# fspy_shm +# `fspy_shm` `fspy_shm` is the private shared-memory layer used by fspy IPC channels. It gives the channel one API for creating a mapping, passing its identifier to another process, and opening additional views of the same bytes. @@ -8,14 +8,14 @@ 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. | -| `open(id)` | Opens another view and derives its size from the operating-system mapping. | -| `Shm::id()` | Returns the identifier to send to another process. | -| `Shm::len()` | Returns the mapped size. | -| `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. | -| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | +| API | Contract | +| ----------------- | ---------------------------------------------------------------------------------- | +| `create(size)` | Creates a non-empty mapping and returns its unique owner. | +| `open(id)` | Opens another view and derives its size from the operating-system mapping. | +| `Shm::id()` | Returns the identifier to send to another process. | +| `Shm::len()` | Returns the mapped size. | +| `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. | +| `Shm::as_slice()` | Returns a shared slice. The caller must prevent mutation for the slice's lifetime. | `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. From 2b0d301fbea3067e83ba66cf650c2813a7d96d03 Mon Sep 17 00:00:00 2001 From: wan9chi Date: Sat, 11 Jul 2026 06:59:53 +0800 Subject: [PATCH 8/8] docs(fspy): keep shared memory API description abstract Co-authored-by: GPT-5 Codex --- crates/fspy_shm/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fspy_shm/README.md b/crates/fspy_shm/README.md index eaddfa76..de20e060 100644 --- a/crates/fspy_shm/README.md +++ b/crates/fspy_shm/README.md @@ -11,7 +11,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. | -| `open(id)` | Opens another view and derives its size from the operating-system mapping. | +| `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. | | `Shm::as_ptr()` | Returns a mutable raw pointer to the first byte. |