Skip to content

SHM handoff - #2646

Open
yellowhatter wants to merge 29 commits into
eclipse-zenoh:mainfrom
ZettaScaleLabs:shm_handoff
Open

SHM handoff#2646
yellowhatter wants to merge 29 commits into
eclipse-zenoh:mainfrom
ZettaScaleLabs:shm_handoff

Conversation

@yellowhatter

@yellowhatter yellowhatter commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

🏷️ Label-Based Checklist

Based on the labels applied to this PR, please complete these additional requirements:

Labels: new feature, breaking-change, release

🆕 New Feature Requirements

Since this PR adds a new feature:

  • Feature scope documented - Clear description of what the feature does and why it's needed
  • Minimum necessary code - Implementation is as simple as possible, doesn't overcomplicate the system
  • New APIs well-designed - Public APIs are intuitive, consistent with existing APIs
  • Comprehensive tests - All functionality is tested (happy path + edge cases + error cases)
  • Examples provided - Usage examples in code comments or separate example files
  • Documentation added - New docs explaining the feature, its use cases, and API
  • Feature flag considered - Can the feature be enabled/disabled for gradual rollout?
  • Performance impact assessed - Memory, CPU, storage implications measured
  • Integration tested - Feature works with existing features

Consider: Can this feature be split into smaller, incremental PRs?

💥 Breaking Change Requirements

Since this PR contains breaking changes:

  • Breaking changes documented - Clear list of what breaks
  • Migration guide provided - Step-by-step instructions for users
  • Deprecation considered - Could this be done with deprecation warnings first?
  • Version bump planned - Major or minor version bump needed
  • Alternatives explored - Why is breaking change necessary?
  • Impact assessed - How many users/use cases affected?

Note: Breaking changes should be discussed with maintainers before implementation.

Instructions:

  1. Check off items as you complete them (change - [ ] to - [x])
  2. The PR checklist CI will verify these are completed

This checklist updates automatically when labels change, but preserves your checked boxes.

Summary

This PR introduces a reliable shared-memory buffer handoff mechanism for unicast transports.

The handoff ensures that a shared-memory buffer remains valid while its corresponding network message is waiting in a transport queue or otherwise in flight. The sender retains a hard reference to every transmitted SHM buffer until the receiver has successfully mounted that buffer.

This prevents SHM buffers from being reclaimed or invalidated when message delivery is delayed by:

  • Transport backpressure
  • Congested or stalled queues
  • Slow receivers
  • Scheduling delays
  • Large reliable-message backlogs

Problem

SHM payloads are transmitted as descriptors rather than copied into the transport message.

Previously, the sender could release its last strong reference after the message had been submitted to the transport. The transport message could then remain queued for longer than the lifetime protected by the normal SHM watchdog/reference mechanism.

In that situation:

  1. The sender serializes an SHM descriptor.
  2. The message waits in a transport queue.
  3. The original SHM buffer reference is released.
  4. The SHM allocation may be invalidated or reused.
  5. The receiver eventually processes a descriptor whose underlying buffer is no longer valid.

A successful enqueue therefore cannot be treated as completion of SHM ownership transfer. Ownership must remain with the sender until the receiver has actually opened and mounted the buffer.

Solution

The PR implements an explicit handoff protocol backed by shared atomic counters.

For every reliable transport direction and priority:

  1. The sender leases a counter from its SHM transport metadata segment.

  2. The counter identifier is exchanged with the peer during transport establishment.

  3. Before enqueueing a message containing SHM buffers, the sender:

    • Creates a hard reference for each buffer.
    • Increments the corresponding shared counter.
    • Stages the references in a handoff transaction.
  4. If the message is accepted by the transport pipeline, the transaction is committed.

  5. If enqueueing fails or the operation is cancelled, the transaction is rolled back automatically.

  6. The receiver mounts each SHM buffer from its descriptor.

  7. Only after a successful mount does the receiver decrement the sender's shared counter.

  8. A sender-side cleanup task observes the counter and releases acknowledged hard references in FIFO order.

sequenceDiagram
    participant TX as Sender
    participant C as Shared counter
    participant Q as Transport queue
    participant RX as Receiver

    TX->>TX: Create ShmBufHardRef
    TX->>C: Increment pending count
    TX->>Q: Enqueue message and SHM descriptor

    alt Enqueue succeeds
        TX->>TX: Commit handoff transaction
        Q->>RX: Deliver message
        RX->>RX: Open and mount SHM buffer
        RX->>C: Decrement pending count
        TX->>TX: Drop acknowledged hard reference
    else Enqueue fails
        TX->>C: Roll back counter increment
        TX->>TX: Drop staged hard reference
    end
Loading

The mechanism uses shared-memory atomics after transport establishment, so it does not require an additional acknowledgement message for every transmitted SHM buffer.

Transport metadata segment

The existing SHM authentication segment is expanded into a transport metadata segment containing:

  • Authentication challenge
  • SHM metadata version
  • Supported SHM protocols
  • A pool of atomic handoff counters

Each process creates a local metadata segment and advertises its segment identifier during SHM negotiation.

The peer opens this segment and validates:

  • The challenge
  • The SHM metadata version
  • The supported protocol information

Counter identifiers are then exchanged during the transport open phase.

Establishment flow

SHM establishment now exchanges the information required for both authentication and handoff.

InitSyn

Alice sends her SHM transport metadata segment identifier.

InitAck

Bob:

  • Opens and validates Alice's segment.
  • Returns Alice's challenge.
  • Sends Bob's metadata segment identifier.

OpenSyn

Alice:

  • Validates Bob's challenge.
  • Leases local transmission counters.
  • Sends the counter identifiers that Bob must decrement after receiving Alice's buffers.

OpenAck

Bob:

  • Leases his own transmission counters.
  • Returns their identifiers to Alice.

After the exchange, each endpoint has:

  • Local counters for buffers it transmits
  • Access to the peer's segment for acknowledging buffers it receives

If the handoff state cannot be completely established, SHM handoff is disabled for that link.

Reliable links and priorities

Handoff tracking is enabled only for reliable communication.

Reliable transports can maintain separate queues for different priorities. A single counter for the entire link would not preserve the ordering relationship between those queues.

The implementation therefore allocates one handoff channel per transport priority. Each channel has:

  • Its own shared counter
  • Its own FIFO of retained hard references
  • Its own acknowledgement and cleanup state

This keeps buffer release ordering aligned with the queue in which the corresponding message was transmitted.

Best-effort communication does not use the handoff mechanism.

Transactional enqueue semantics

SHM references and counter increments are managed through a handoff transaction.

When a message is mapped for transmission, each SHM slice added to the message is registered with the current transaction.

The transaction remains uncommitted until the transport pipeline accepts the message.

Successful enqueue

When the message is accepted:

  • Staged hard references are moved into the committed FIFO.
  • The shared counter increments remain active.
  • The references stay alive until acknowledged by the receiver.

Failed or cancelled enqueue

When the message is rejected, dropped or cancelled:

  • Counter increments are reverted.
  • Staged references are released.
  • No phantom in-flight buffers remain in the handoff state.

The transaction automatically cancels itself when dropped without an explicit commit, which protects early-return and error paths.

Receive-side semantics

When receiving a message containing an SHM descriptor, the receiver:

  1. Deserializes the SHM buffer information.
  2. Opens and mounts the corresponding buffer.
  3. Replaces the serialized slice with the mounted SHM buffer.
  4. Decrements the sender's handoff counter for the message priority.

The counter is decremented only after the buffer has been mounted successfully.

Consequently, a malformed descriptor, unsupported protocol or mount failure cannot incorrectly tell the sender that ownership has been transferred.

Hard references

The PR adds ShmBufHardRef, which retains the confirmed SHM metadata/watchdog ownership required to keep an allocation valid.

Hard references can be created from the supported SHM buffer wrapper types and are stored by the TX handoff queues while buffers are in flight.

The actual payload is not copied. The reference exists only to prevent premature SHM invalidation or reuse.

Sender-side cleanup

Committed references are stored in FIFO order.

A periodic cleanup task compares:

  • The number of locally retained references
  • The number of buffers still reported as pending by the shared counter

When the receiver decrements the counter, the cleanup task removes the corresponding number of references from the front of the FIFO.

This means:

  • References are retained while the receiver still reports them as pending.
  • Acknowledged references are eventually released.
  • No per-buffer response packet is required.
  • Release may occur shortly after acknowledgement rather than synchronously with it.

If a receiver remains connected but never mounts a buffer, the reference intentionally remains retained. This favors memory safety over prematurely reclaiming an allocation that may still be consumed.

Main implementation changes

zenoh-shm

  • Adds ShmBufHardRef.
  • Reworks confirmed descriptor ownership around the SHM watchdog.
  • Introduces TX and RX handoff counter leases.
  • Extends the SHM metadata segment with the counter pool.
  • Adds segment and shared-structure equality support.
  • Increments the SHM metadata version to reflect the new layout.

SHM codecs

  • Adds codecs for SHM segment references.
  • Adds codecs for structures stored in SHM segments.
  • Encodes segment identifiers and reopens the corresponding segment while decoding.

Transport protocol

  • Changes the SHM open extension from a scalar value to a buffer capable of carrying the expanded establishment data.
  • Exchanges metadata segment identifiers, challenges and counter identifiers.
  • Stores established TX and RX handoff state in the SHM negotiation FSM.

Unicast transport

  • Adds per-link TX and RX handoff configuration.
  • Integrates handoff transactions into SHM message mapping.
  • Commits handoff state only after successful pipeline enqueue.
  • Passes receive-side handoff state into SHM buffer mounting.
  • Propagates the configuration through the universal and low-latency transport structures.

Common transport utilities

  • Adds a reusable priority-indexed container.
  • Adds enabled and disabled handoff configurations.
  • Keeps non-SHM and best-effort paths free from handoff bookkeeping.

Failure and lifecycle behavior

The implementation is designed to preserve the following invariants:

  • Every committed TX hard reference has a corresponding increment in a shared counter.
  • A counter is decremented only after successful RX mounting.
  • References are released in the same FIFO domain in which they were registered.
  • Failed enqueue operations do not leave counters incremented.
  • Dropped uncommitted transactions automatically roll back.
  • Closing a handoff channel stops its cleanup task.
  • Destroying the channel releases any references still owned locally.
  • Counter leases return their counter identifiers to the segment pool when dropped.

Compatibility

The SHM metadata version is increased because the shared segment layout and establishment data have changed.

Peers must agree on the SHM metadata version before using the new metadata segment. An incompatible peer must not interpret the new segment layout or use its counters.

The SHM open-extension wire representation also changes to carry the expanded negotiation payload.

These changes affect SHM negotiation rather than ordinary non-SHM payload transport. No application-level API changes are required to benefit from the handoff mechanism.

Performance and resource impact

For each reliable transport direction, the handoff introduces:

  • One shared atomic counter per priority
  • One retained hard reference per in-flight SHM slice
  • A local FIFO used to track committed references
  • Periodic cleanup of acknowledged references

Counter acknowledgements are direct shared-memory atomic operations and do not generate additional network messages.

Best-effort links and messages without SHM buffers do not retain SHM references through this mechanism.

Memory use is proportional to the number of SHM slices that have been committed to the transport but have not yet been acknowledged by the receiver.

Reviewer focus areas

The most important areas to review are:

  • Counter/reference consistency across all enqueue outcomes
  • FIFO assumptions within each transport priority
  • Multiple-SHM-slice accounting
  • Cleanup-task cancellation and link teardown
  • Peer disconnect behavior with outstanding references
  • Counter lease reuse and exhaustion
  • SHM version and wire-format compatibility
  • Coverage of every congestion-control path

Expected result

After this change, an SHM buffer queued on a reliable unicast transport remains valid until the receiver has successfully mounted it, regardless of how long the message spends waiting in the transport queue.

This preserves zero-copy SHM delivery while preventing premature buffer invalidation under backpressure or prolonged queue stalls.

@yellowhatter yellowhatter self-assigned this Jun 16, 2026
@yellowhatter yellowhatter added enhancement Existing things could work better new feature Something new is needed release Part of the next release labels Jul 7, 2026
@yellowhatter
yellowhatter marked this pull request as ready for review July 7, 2026 07:50
@doisyg

doisyg commented Jul 13, 2026

Copy link
Copy Markdown

Any progress there ?
Is this worth to test ?

@yellowhatter

Copy link
Copy Markdown
Contributor Author

Any progress there ? Is this worth to test ?

Hi @doisyg ! This is still WIP, ETA this week. Not yet testable.

@diogomatsubara diogomatsubara added this to the 1.10.0 milestone Jul 20, 2026
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.13924% with 77 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.69%. Comparing base (2b17838) to head (9672773).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...sport/src/unicast/establishment/ext/shm/segment.rs 77.70% 33 Missing ⚠️
commons/zenoh-codec/src/core/shm.rs 0.00% 14 Missing ⚠️
commons/zenoh-shm/src/lib.rs 40.00% 9 Missing ⚠️
...ransport/src/unicast/establishment/ext/shm/auth.rs 86.66% 8 Missing ⚠️
io/zenoh-transport/src/common/shm/handoff.rs 93.61% 3 Missing ⚠️
...sport/src/unicast/establishment/ext/shm/handoff.rs 99.20% 2 Missing ⚠️
io/zenoh-transport/src/unicast/lowlatency/rx.rs 84.61% 2 Missing ⚠️
io/zenoh-transport/src/unicast/universal/rx.rs 90.90% 2 Missing ⚠️
io/zenoh-transport/src/common/shm/interop.rs 99.30% 1 Missing ⚠️
...enoh-transport/src/unicast/establishment/accept.rs 95.23% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2646      +/-   ##
==========================================
+ Coverage   74.48%   74.69%   +0.20%     
==========================================
  Files         423      425       +2     
  Lines       63056    63725     +669     
==========================================
+ Hits        46967    47598     +631     
- Misses      16089    16127      +38     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@yellowhatter

Copy link
Copy Markdown
Contributor Author

Hi @doisyg ! You may try SHM handoff PR since now. I'm still making some tests for it, so not guaranteed to be bug-free, but should work.

@yellowhatter yellowhatter changed the title WIP on SHM handoff SHM handoff Jul 21, 2026
@yellowhatter yellowhatter removed the enhancement Existing things could work better label Jul 21, 2026
@fuzzypixelz fuzzypixelz added the breaking-change Indicates that the issue implies a breaking change (be it at compile time or at runtime) label Jul 21, 2026
@YuanYuYuan

YuanYuYuan commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Concurrency issue in TxHandoff staging (likely blocking)

TxHandoffInner::not_commit (io/zenoh-transport/src/unicast/establishment/ext/shm/handoff.rs) is a single Mutex<VecDeque<ShmBufHardRef>> shared per (link, priority). Every TxHandoffTransaction for that priority clones the same Arc, so concurrent transactions' push()/commit()/cancel() all touch the same queue with no isolation between them.

Nothing serializes this upstream: in internal_schedule (unicast/universal/tx.rs), the links read-lock is dropped before pipeline.push_network_message is called, and the pipeline's own per-priority mutex is only acquired inside that call — after the handoff push() has already staged. So two same-priority sends on the same link can race.

Failure mode: transaction A pushes, then transaction B pushes and commits. B's commit() drains the whole queue, including A's still-staged entry. If A's own send then fails, A's Drop::cancel() finds the queue already empty — a no-op — so A's counter increment is never rolled back and A's hard ref sits in the handoff queue forever, waiting on an RX ack that will never come. That's the same class of leak this PR is meant to fix, reintroduced under concurrent same-priority sends.

I confirmed this with a unit test against the current head (two threads sharing one TxHandoff, barrier-synced to force the race), which fails as predicted:

assertion `left == right` failed: expected only B's transaction to be committed;
got 2 committed entries — A's uncommitted push leaked into B's commit
  left: 2
 right: 1

Suggested fix: stage per-transaction (e.g. a local buffer inside TxHandoffTransaction, merged into the shared queue only from commit()/cancel()) — unless same-priority internal_schedule calls are meant to be serialized by some guarantee elsewhere in the transport that isn't visible from this diff, in which case it'd be worth documenting.

Reproducible test: https://gist.github.com/YuanYuYuan/95382b2e9b1618871cff18416a3008b1

challenge: u64,
version: u64,
protocols: [ProtocolID; 256],
shm_counters: [AtomicU32; 762],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that within a link 1 SHM counter is used per-channel and hence per-priority. Meaning 8 counters per-link, right ?
762 counters allow to handle 95 links, limiting the number of peers in a p2p system to 96 peers.
That will not be sufficient for some ROS 2 systems where more than 200 peers are deployed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was planning to make growing counter segment based on overcommit mechanics.
Now I made fixed-size array for 351 peer


let c_task = task.clone();
let c_token = token.clone();
ZRuntime::Net.spawn(async move {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean a new task is created for each SHM counter ?
In large p2p systems with many links, might this result in too many tasks that will wake-up every 100ms ?

On the other hand, 100ms sleep seems quite large in case of high frequency of messages. At 100Hz it means 10 messages are retained per-cycle in SHM before to be cleaned-up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made one single global task

let smb = shmr.read_shmbuf(shmbinfo)?;

// Handle RX handoff
handoff.on_rx(priority);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the deserialization of shminfo fails, this handoff is never called, causing a leak.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Conflicts:
	io/zenoh-transport/src/lib.rs
	io/zenoh-transport/src/manager.rs
	io/zenoh-transport/src/unicast/universal/link.rs
- few improvements around SHM codbase
- fix handoff counter leakage in case of SHM slice mount error
- increase SHM counters count to handle 352 priority-enabled peers
- improve shm counters memory writes
- fix SHM counters zero issue
@yellowhatter

Copy link
Copy Markdown
Contributor Author

Concurrency issue in TxHandoff staging (likely blocking)

TxHandoffInner::not_commit (io/zenoh-transport/src/unicast/establishment/ext/shm/handoff.rs) is a single Mutex<VecDeque<ShmBufHardRef>> shared per (link, priority). Every TxHandoffTransaction for that priority clones the same Arc, so concurrent transactions' push()/commit()/cancel() all touch the same queue with no isolation between them.

Nothing serializes this upstream: in internal_schedule (unicast/universal/tx.rs), the links read-lock is dropped before pipeline.push_network_message is called, and the pipeline's own per-priority mutex is only acquired inside that call — after the handoff push() has already staged. So two same-priority sends on the same link can race.

Failure mode: transaction A pushes, then transaction B pushes and commits. B's commit() drains the whole queue, including A's still-staged entry. If A's own send then fails, A's Drop::cancel() finds the queue already empty — a no-op — so A's counter increment is never rolled back and A's hard ref sits in the handoff queue forever, waiting on an RX ack that will never come. That's the same class of leak this PR is meant to fix, reintroduced under concurrent same-priority sends.

I confirmed this with a unit test against the current head (two threads sharing one TxHandoff, barrier-synced to force the race), which fails as predicted:

assertion `left == right` failed: expected only B's transaction to be committed;
got 2 committed entries — A's uncommitted push leaked into B's commit
  left: 2
 right: 1

Suggested fix: stage per-transaction (e.g. a local buffer inside TxHandoffTransaction, merged into the shared queue only from commit()/cancel()) — unless same-priority internal_schedule calls are meant to be serialized by some guarantee elsewhere in the transport that isn't visible from this diff, in which case it'd be worth documenting.

Reproducible test: https://gist.github.com/YuanYuYuan/95382b2e9b1618871cff18416a3008b1

Fixed! Made priority channel locking

Conflicts:
	io/zenoh-transport/src/common/shm/interop.rs
	io/zenoh-transport/src/common/shm/shm_context.rs
	io/zenoh-transport/src/multicast/tx.rs
	io/zenoh-transport/src/shm.rs
	io/zenoh-transport/src/shm_context.rs
	io/zenoh-transport/src/unicast/lowlatency/tx.rs
	io/zenoh-transport/src/unicast/universal/tx.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a shared-memory (SHM) buffer handoff protocol for reliable unicast transports so SHM-backed payloads remain valid while queued/in-flight, using per-priority shared atomic counters and transactional enqueue semantics integrated into SHM mapping and transport establishment.

Changes:

  • Extends SHM negotiation to exchange metadata-segment IDs, challenges, and per-priority counter identifiers (breaking wire-format/layout changes).
  • Adds TX/RX handoff tracking and transactional commit/rollback into unicast universal + low-latency paths and SHM interop mapping.
  • Adds a stalled-queue SHM regression test to validate buffers remain SHM-backed under backpressure/queue stalls.

Reviewed changes

Copilot reviewed 45 out of 46 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
zenoh/src/net/runtime/mod.rs Updates SHM provider init state import to new transport SHM module location.
io/zenoh-transport/tests/unicast_shm.rs Adds stalled-queue test coverage to ensure SHM buffers survive prolonged queuing.
io/zenoh-transport/src/unicast/universal/tx.rs Integrates SHM partner mapping with handoff transaction commit on successful enqueue.
io/zenoh-transport/src/unicast/universal/transport.rs Updates SHM context import path for universal unicast transport.
io/zenoh-transport/src/unicast/universal/rx.rs Threads per-link RX SHM handoff into SHM mounting on receive.
io/zenoh-transport/src/unicast/universal/link.rs Adjusts RX loop to pass link wrapper (incl. SHM state) into message reading.
io/zenoh-transport/src/unicast/mod.rs Updates SHM config import path.
io/zenoh-transport/src/unicast/manager.rs Updates SHM context/config imports to new common SHM module structure.
io/zenoh-transport/src/unicast/lowlatency/tx.rs Removes legacy low-latency TX scheduling path (replaced by link-based send).
io/zenoh-transport/src/unicast/lowlatency/transport.rs Simplifies schedule path to use send() and updates SHM context import.
io/zenoh-transport/src/unicast/lowlatency/rx.rs Adds RX handoff integration during SHM buffer mapping in low-latency receive path.
io/zenoh-transport/src/unicast/lowlatency/mod.rs Drops low-latency tx module after refactor.
io/zenoh-transport/src/unicast/lowlatency/link.rs Implements low-latency send with SHM mapping + handoff commit and updated RX plumbing.
io/zenoh-transport/src/unicast/link.rs Adds per-link SHM handoff configuration/state to transport links.
io/zenoh-transport/src/unicast/establishment/open.rs Refactors SHM establishment FSM to produce transport SHM config + per-link handoff config.
io/zenoh-transport/src/unicast/establishment/ext/shm/segment.rs Introduces SHM transport metadata segment layout including counter pool.
io/zenoh-transport/src/unicast/establishment/ext/shm/mod.rs Adds SHM establishment submodules (auth/handoff/segment).
io/zenoh-transport/src/unicast/establishment/ext/shm/handoff.rs Implements TX/RX handoff channels, storage, and transactional semantics.
io/zenoh-transport/src/unicast/establishment/ext/shm/auth.rs Expands SHM extension from scalar challenge to buffer payload carrying handoff establishment data.
io/zenoh-transport/src/unicast/establishment/cookie.rs Updates cookie SHM accept/open state type paths after SHM FSM refactor.
io/zenoh-transport/src/unicast/establishment/accept.rs Mirrors open-side SHM FSM refactor on accept side; extracts link handoff config.
io/zenoh-transport/src/multicast/tx.rs Updates SHM partner mapping call site to new signature (handoff disabled for multicast).
io/zenoh-transport/src/multicast/transport.rs Updates multicast SHM context import path.
io/zenoh-transport/src/multicast/rx.rs Updates SHM RX mapping call site to new signature (handoff disabled for multicast).
io/zenoh-transport/src/multicast/establishment.rs Updates multicast SHM context construction path.
io/zenoh-transport/src/manager.rs Updates SHM context import path for transport manager.
io/zenoh-transport/src/lib.rs Removes legacy shm/shm_context modules from crate root.
io/zenoh-transport/src/common/shm/shm_context.rs Makes SHM contexts public(crate) and transitions to new common SHM module layout.
io/zenoh-transport/src/common/shm/mod.rs Adds common SHM module entrypoint and re-exports provider init state.
io/zenoh-transport/src/common/shm/interop.rs Updates SHM mapping interop to support handoff transactions and per-link RX acknowledgements.
io/zenoh-transport/src/common/shm/handoff.rs Adds shared priority-indexed container used by handoff configuration.
io/zenoh-transport/src/common/mod.rs Exposes common SHM module behind shared-memory feature.
io/zenoh-transport/Cargo.toml Adds lockfree and static_init dependencies for SHM handoff reactor/storage.
commons/zenoh-shm/src/watchdog/confirmator.rs Adjusts confirmed descriptor bookkeeping to use watchdog ownership consistently.
commons/zenoh-shm/src/version.rs Bumps SHM metadata/layout version to reflect new transport metadata segment format.
commons/zenoh-shm/src/shm/mod.rs Adds Eq/PartialEq based on segment ID to support equality checks.
commons/zenoh-shm/src/posix_shm/struct_in_shm.rs Adds Eq/PartialEq impls for StructInSHM.
commons/zenoh-shm/src/posix_shm/segment.rs Derives Eq/PartialEq for POSIX SHM segment wrapper.
commons/zenoh-shm/src/posix_shm/mod.rs Makes segment module public and adjusts module exports.
commons/zenoh-shm/src/metadata/descriptor.rs Exposes watchdog field for hard-reference construction.
commons/zenoh-shm/src/lib.rs Adds ShmBufHardRef type to retain confirmed ownership of SHM allocations.
commons/zenoh-protocol/src/transport/open.rs Changes SHM open extension wire type from z64 to zbuf (breaking protocol change).
commons/zenoh-codec/src/core/shm.rs Adds codecs for SHM segment/StructInSHM identifiers (open/reopen on decode).
commons/zenoh-codec/Cargo.toml Adds rand dependency required by new codecs.
Cargo.toml Adds lockfree to workspace dependencies.
Cargo.lock Records new lockfree/owned-alloc/static_init dependency resolution.
Suppressed comments (3)

io/zenoh-transport/src/common/shm/interop.rs:311

  • In map_zmsg_to_partner, the Response branch gates implicit SHM optimization on policy.query, but replies/errors should be controlled by policy.reply (as documented in ShmOptimizationPolicy). As written, the Reply/Err categories will ignore the reply flag and instead follow the query setting.
    io/zenoh-transport/src/common/shm/shm_context.rs:24
  • This import block pulls LazyShmProvider/*TransportShmConfig from both crate::common::shm::interop and crate::shm, and also imports AuthUnicast twice (auth::AuthUnicast, AuthUnicast). This is currently a name collision and also references crate::shm even though the transport crate no longer exposes a shm module in lib.rs.
    io/zenoh-transport/src/common/shm/interop.rs:439
  • RX handoff acknowledgement is performed unconditionally for every ShmPtr slice, even when map_zslice_to_shmbuf fails. This can decrement the sender's handoff counter despite a mount/validation error, violating the invariant that counters are decremented only after a successful mount.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +79 to +81
fn protocols(&self) -> &[ProtocolID] {
&self.protocols[..self.id_count as usize]
}
Comment on lines +73 to +82
pub fn new_rx(segment: &Arc<RXAuthSegment>, ids: HandoffCounterIds) -> Self {
match ids {
HandoffCounterIds::Disabled => Self::Disabled,
HandoffCounterIds::PerPrio(prio_container) => {
let prio_container = prio_container
.map(|counter_id| ShmRXCounterLease::new(segment.clone(), counter_id));
Self::PerPrio(prio_container)
}
}
}
Comment on lines +214 to +218
// SAFETY: this is safe because we store Arc to inner together with this reference. Should
// track that reference never leaves LockedTxHandoff
let lock: std::sync::MutexGuard<'static, VecDeque<ShmBufHardRef>> =
unsafe { std::mem::transmute(lock) };
LockedTxHandoff { inner, lock }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Indicates that the issue implies a breaking change (be it at compile time or at runtime) new feature Something new is needed release Part of the next release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants