Preview of the proposed up-rust native-frame-model branch (up-rust b6b99c6d, up-spec f0e9b17) — not released documentation. branch · write-up

up_rust/zero_copy/
transport.rs

1/********************************************************************************
2 * Copyright (c) 2026 Contributors to the Eclipse Foundation
3 *
4 * See the NOTICE file(s) distributed with this work for additional
5 * information regarding copyright ownership.
6 *
7 * This program and the accompanying materials are made available under the
8 * terms of the Apache License Version 2.0 which is available at
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 ********************************************************************************/
13
14use super::*;
15
16mod zero_copy_transport_sealed {
17    pub trait Sealed {}
18}
19
20#[cfg(feature = "zero-copy-transport")]
21mod zero_copy_uninit_transport_sealed {
22    pub trait Sealed {}
23}
24
25/// Send-side timings emitted by the hidden stable-payload diagnostic API.
26#[cfg(feature = "perf-diagnostics")]
27#[doc(hidden)]
28#[derive(Clone, Copy, Debug, Eq, PartialEq)]
29pub struct UninitStableSendPhases {
30    pub prepare: std::time::Duration,
31    pub loan: std::time::Duration,
32    pub verify: std::time::Duration,
33    pub initialize: std::time::Duration,
34    pub witness: std::time::Duration,
35    pub commit: std::time::Duration,
36    pub total: std::time::Duration,
37    pub residual: std::time::Duration,
38}
39
40#[cfg(feature = "perf-diagnostics")]
41impl UninitStableSendPhases {
42    #[must_use]
43    pub fn accounted(self) -> std::time::Duration {
44        self.prepare + self.loan + self.verify + self.initialize + self.witness + self.commit
45    }
46
47    /// Measures the median back-to-back `Instant` acquisition cost.
48    #[must_use]
49    pub fn calibrate_clock_overhead(iterations: usize) -> std::time::Duration {
50        let mut samples = Vec::with_capacity(iterations.max(1));
51        for _ in 0..iterations.max(1) {
52            let start = std::time::Instant::now();
53            samples.push(start.elapsed());
54        }
55        samples.sort_unstable();
56        *samples
57            .get(samples.len() / 2)
58            .expect("clock calibration always records at least one sample")
59    }
60}
61
62#[cfg(feature = "zero-copy-transport")]
63fn initialize_stable_tx_payload<B, T>(
64    buffer: &mut B,
65    init: impl for<'payload> FnOnce(
66        StablePayloadInitContext<'payload, T>,
67    ) -> Result<InitializedStablePayload<'payload, T>, UWireError>,
68) -> Result<(), UStatus>
69where
70    B: UUninitTxBuffer,
71    T: StablePayloadInit,
72{
73    let payload = buffer.payload_uninit_mut();
74    // SAFETY: the caller obtained `buffer` from the uninitialized transport
75    // loan API and verified its visible payload layout before this helper.
76    let loaned = unsafe {
77        LoanedPayloadUninitMut::new_unchecked(payload, PayloadLoanProvenance::OpaqueTransportLoan)
78    };
79    let initializer = T::init_from_uninit_payload(loaned).map_err(UStatus::from)?;
80    let context = StablePayloadInitContext::new(initializer);
81    let _ = init(context).map_err(UStatus::from)?;
82    Ok(())
83}
84
85/// *Role: implemented by transports whose API speaks the library's frame types; users call [`UZeroCopyTransport`](crate::UZeroCopyTransport) — see the [trait map](crate::guide::trait_map).*
86///
87/// Semantic native-frame implementation boundary for zero-copy transports.
88///
89/// Implementing this trait buys the validated public [`UZeroCopyTransport`]
90/// API, listener filter validation, receive-frame validation, codec extension
91/// helpers, and stable-payload initialization. This seam receives validated
92/// [`UFrameMetadata`]. A physical transport that should carry encoded metadata
93/// bytes without semantic knowledge implements `UZeroCopyTransportCore`
94/// instead and is wrapped by the selected-wire adapter.
95///
96/// Two operations are required: reserve a validated TX loan and commit it.
97/// Pull receive and listener registration/unregistration have default
98/// unsupported implementations; override only the carriage patterns the
99/// technology supports. [`UZeroCopyUninitTransportImpl`] adds the optional
100/// uninitialized-TX capability.
101///
102/// The transport must honor or reject the validated payload layout, keep TX
103/// loans exclusive until commit, and keep RX leases immutable until release
104/// (`req~zero-copy-alignment~1`, `req~zero-copy-loan-isolation~1`, and
105/// `req~zero-copy-lease-immutability~1`). `InMemoryZeroCopyTransport` under
106/// `test-util` is the semantic reference implementation.
107#[async_trait]
108pub trait UZeroCopyTransportImpl: Send + Sync {
109    /// Transport-specific transmit loan type.
110    type Tx: UTxBuffer + Send;
111
112    /// Transport-specific receive lease type.
113    type Rx: UZeroCopyRxLease + Send + 'static;
114
115    /// Reserves transmit storage for a validated frame loan spec.
116    async fn loan_validated_tx(&self, spec: UTxLoanSpec) -> Result<Self::Tx, UStatus>;
117
118    /// Commits a validated transmit loan.
119    async fn send_validated_zero_copy(&self, buffer: Self::Tx) -> Result<(), UStatus>;
120
121    /// Receives one matching zero-copy frame from transports that support pull receive.
122    async fn receive_validated_zero_copy(
123        &self,
124        _source_filter: &UUri,
125        _sink_filter: Option<&UUri>,
126    ) -> Result<Self::Rx, UStatus> {
127        Err(UStatus::fail_with_code(
128            UCode::Unimplemented,
129            "not implemented",
130        ))
131    }
132
133    /// Registers a zero-copy listener after public filter validation.
134    async fn register_validated_zero_copy_listener(
135        &self,
136        _source_filter: &UUri,
137        _sink_filter: Option<&UUri>,
138        _listener: Arc<dyn UZeroCopyListener<Self::Rx>>,
139    ) -> Result<(), UStatus> {
140        Err(UStatus::fail_with_code(
141            UCode::Unimplemented,
142            "not implemented",
143        ))
144    }
145
146    /// Unregisters a zero-copy listener after public filter validation.
147    async fn unregister_validated_zero_copy_listener(
148        &self,
149        _source_filter: &UUri,
150        _sink_filter: Option<&UUri>,
151        _listener: Arc<dyn UZeroCopyListener<Self::Rx>>,
152    ) -> Result<(), UStatus> {
153        Err(UStatus::fail_with_code(
154            UCode::Unimplemented,
155            "not implemented",
156        ))
157    }
158}
159
160impl<T> zero_copy_transport_sealed::Sealed for T where T: UZeroCopyTransportImpl + ?Sized {}
161
162/// *Role: called by users of the zero-copy family; transports implement [`UZeroCopyTransportImpl`](crate::UZeroCopyTransportImpl) or the encoded core instead — see the [trait map](crate::guide::trait_map).*
163///
164/// The zero-copy transport capability API.
165#[async_trait]
166pub trait UZeroCopyTransport: zero_copy_transport_sealed::Sealed + Send + Sync {
167    /// Transport-specific transmit loan type returned by [`Self::loan_tx`].
168    type Tx: UTxBuffer + Send;
169
170    /// Transport-specific receive lease type returned by pull receive and listeners.
171    type Rx: UZeroCopyRxLease + Send + 'static;
172
173    /// Reserves transmit storage for a validated frame loan spec.
174    async fn loan_tx(&self, spec: UTxLoanSpec) -> Result<Self::Tx, UStatus>;
175
176    /// Commits a previously reserved transmit loan.
177    async fn send_zero_copy(&self, buffer: Self::Tx) -> Result<(), UStatus>;
178
179    /// Receives one matching zero-copy frame from transports that support pull receive.
180    async fn receive_zero_copy(
181        &self,
182        source_filter: &UUri,
183        sink_filter: Option<&UUri>,
184    ) -> Result<Self::Rx, UStatus>;
185
186    /// Registers a listener for matching zero-copy receive leases.
187    async fn register_zero_copy_listener(
188        &self,
189        source_filter: &UUri,
190        sink_filter: Option<&UUri>,
191        listener: Arc<dyn UZeroCopyListener<Self::Rx>>,
192    ) -> Result<(), UStatus>;
193
194    /// Unregisters a listener for matching zero-copy receive leases.
195    async fn unregister_zero_copy_listener(
196        &self,
197        source_filter: &UUri,
198        sink_filter: Option<&UUri>,
199        listener: Arc<dyn UZeroCopyListener<Self::Rx>>,
200    ) -> Result<(), UStatus>;
201}
202
203#[async_trait]
204impl<T> UZeroCopyTransport for T
205where
206    T: UZeroCopyTransportImpl + ?Sized,
207{
208    type Tx = T::Tx;
209    type Rx = T::Rx;
210
211    async fn loan_tx(&self, spec: UTxLoanSpec) -> Result<Self::Tx, UStatus> {
212        UZeroCopyTransportImpl::loan_validated_tx(self, spec).await
213    }
214
215    async fn send_zero_copy(&self, mut buffer: Self::Tx) -> Result<(), UStatus> {
216        validate_tx_buffer_for_transport(&mut buffer)?;
217        UZeroCopyTransportImpl::send_validated_zero_copy(self, buffer).await
218    }
219
220    async fn receive_zero_copy(
221        &self,
222        source_filter: &UUri,
223        sink_filter: Option<&UUri>,
224    ) -> Result<Self::Rx, UStatus> {
225        verify_zero_copy_filter_criteria(source_filter, sink_filter)?;
226        let frame =
227            UZeroCopyTransportImpl::receive_validated_zero_copy(self, source_filter, sink_filter)
228                .await?;
229        validate_frame_view_for_transport(&frame)?;
230        Ok(frame)
231    }
232
233    async fn register_zero_copy_listener(
234        &self,
235        source_filter: &UUri,
236        sink_filter: Option<&UUri>,
237        listener: Arc<dyn UZeroCopyListener<Self::Rx>>,
238    ) -> Result<(), UStatus> {
239        verify_zero_copy_filter_criteria(source_filter, sink_filter)?;
240        let key = zero_copy_listener_registration_key(
241            self,
242            source_filter,
243            sink_filter,
244            zero_copy_listener_pointer(&listener),
245        );
246        let (listener, inserted) = registered_zero_copy_listener(&key, listener);
247        let result = UZeroCopyTransportImpl::register_validated_zero_copy_listener(
248            self,
249            source_filter,
250            sink_filter,
251            listener,
252        )
253        .await;
254        if result.is_err() && inserted {
255            ZERO_COPY_LISTENER_REGISTRY
256                .lock()
257                .expect("zero-copy listener registry lock poisoned")
258                .remove(&key);
259        }
260        result
261    }
262
263    async fn unregister_zero_copy_listener(
264        &self,
265        source_filter: &UUri,
266        sink_filter: Option<&UUri>,
267        listener: Arc<dyn UZeroCopyListener<Self::Rx>>,
268    ) -> Result<(), UStatus> {
269        verify_zero_copy_filter_criteria(source_filter, sink_filter)?;
270        let key = zero_copy_listener_registration_key(
271            self,
272            source_filter,
273            sink_filter,
274            zero_copy_listener_pointer(&listener),
275        );
276        let listener = zero_copy_listener_for_unregister(&key, listener);
277        let result = UZeroCopyTransportImpl::unregister_validated_zero_copy_listener(
278            self,
279            source_filter,
280            sink_filter,
281            listener,
282        )
283        .await;
284        if result.is_ok() {
285            ZERO_COPY_LISTENER_REGISTRY
286                .lock()
287                .expect("zero-copy listener registry lock poisoned")
288                .remove(&key);
289        }
290        result
291    }
292}
293
294/// *Role: free blanket methods on every zero-copy transport; never implemented by hand — see the [trait map](crate::guide::trait_map).*
295///
296/// Convenience methods for zero-copy transports with initialized TX storage.
297#[async_trait]
298pub trait UZeroCopyTransportExt: UZeroCopyTransport {
299    /// Initializes a typed payload using the adapter's selected wire and sends it.
300    ///
301    /// Prefer this selected-wire helper on values produced by explicit selected-wire adapter construction.
302    /// Use [`Self::send_loaned_payload_as`] only for low-level codec escape hatches.
303    ///
304    /// # Errors
305    ///
306    /// Returns an error if the selected wire does not successfully loan, encode,
307    /// or send the payload through the underlying transport.
308    #[cfg(feature = "selected-wire-transport-adapter")]
309    async fn send_loaned_payload<T>(
310        &self,
311        metadata: UFrameMetadata,
312        init: impl for<'payload> FnOnce(&'payload mut T) + Send,
313    ) -> Result<(), UStatus>
314    where
315        Self: UHasWire,
316        Self::Wire: UWirePayload<T>,
317        <Self::Wire as UWirePayload<T>>::Codec: LoanPayload<T> + Send + Sync,
318    {
319        self.send_loaned_payload_as::<<Self::Wire as UWirePayload<T>>::Codec, T>(metadata, init)
320            .await
321    }
322
323    /// Initializes a typed payload directly in a transmit loan and sends it.
324    ///
325    /// This is the low-level codec-selected form. Product code that already uses
326    /// explicit selected-wire adapter construction should prefer
327    /// `send_loaned_payload` so the
328    /// selected wire supplies the payload codec.
329    ///
330    /// # Errors
331    ///
332    /// Returns an error if metadata validation fails, the transport cannot loan
333    /// the requested initialized layout, the codec rejects the loaned storage, or
334    /// sending the committed loan fails.
335    async fn send_loaned_payload_as<C, T>(
336        &self,
337        metadata: UFrameMetadata,
338        init: impl for<'payload> FnOnce(&'payload mut T) + Send,
339    ) -> Result<(), UStatus>
340    where
341        C: PayloadCodec + LoanPayload<T> + Send + Sync,
342    {
343        let metadata = metadata
344            .with_payload_encoding(C::payload_encoding())
345            .map_err(frame_metadata_error)?;
346        let layout = C::loan_layout().map_err(UStatus::from)?;
347        let mut buffer = self
348            .loan_tx(UTxLoanSpec::payload(
349                metadata,
350                layout.len(),
351                layout.align(),
352            )?)
353            .await?;
354        verify_tx_buffer_payload_layout(&mut buffer, layout.len(), layout.align())?;
355        {
356            let payload = C::loan_payload(buffer.payload_mut()).map_err(UStatus::from)?;
357            init(payload);
358        }
359        self.send_zero_copy(buffer).await
360    }
361}
362
363impl<T> UZeroCopyTransportExt for T where T: UZeroCopyTransport + ?Sized {}
364
365/// *Role: free blanket methods for typed initialization into uninitialized loans; never implemented by hand — see the [trait map](crate::guide::trait_map).*
366///
367/// Convenience methods for zero-copy transports with uninitialized TX storage.
368#[cfg(feature = "zero-copy-transport")]
369#[async_trait]
370pub trait UZeroCopyUninitTransportExt: UZeroCopyUninitTransport {
371    /// Constructs a typed payload using the adapter's selected wire and sends it.
372    ///
373    /// Prefer this selected-wire helper on values produced by explicit selected-wire adapter construction.
374    /// Use [`Self::send_uninit_loaned_payload_as`] only for low-level codec
375    /// escape hatches.
376    ///
377    /// # Errors
378    ///
379    /// Returns an error if metadata validation, loaning, initialization, or send
380    /// fails.
381    #[cfg(feature = "selected-wire-transport-adapter")]
382    async fn send_uninit_loaned_payload<T>(
383        &self,
384        metadata: UFrameMetadata,
385        init: impl for<'payload> FnOnce(
386                LoanedUninitPayload<'payload, T>,
387            ) -> Result<LoanedInitPayload<'payload, T>, UWireError>
388            + Send,
389    ) -> Result<(), UStatus>
390    where
391        Self: UHasWire,
392        Self::Wire: UWirePayload<T>,
393        <Self::Wire as UWirePayload<T>>::Codec: LoanUninitPayload<T> + Send + Sync,
394        T: Send,
395    {
396        self.send_uninit_loaned_payload_as::<<Self::Wire as UWirePayload<T>>::Codec, T>(
397            metadata, init,
398        )
399        .await
400    }
401
402    /// Constructs a typed payload directly in uninitialized transmit storage and sends it.
403    ///
404    /// This is the low-level codec-selected form. Product code that already uses
405    /// explicit selected-wire adapter construction should prefer
406    /// `send_uninit_loaned_payload` so the
407    /// selected wire supplies the payload codec.
408    ///
409    /// # Errors
410    ///
411    /// Returns an error if metadata validation fails, the transport cannot loan
412    /// the requested uninitialized layout, the codec rejects the loaned storage,
413    /// the initializer fails, or sending the committed loan fails.
414    async fn send_uninit_loaned_payload_as<C, T>(
415        &self,
416        metadata: UFrameMetadata,
417        init: impl for<'payload> FnOnce(
418                LoanedUninitPayload<'payload, T>,
419            ) -> Result<LoanedInitPayload<'payload, T>, UWireError>
420            + Send,
421    ) -> Result<(), UStatus>
422    where
423        C: PayloadCodec + LoanUninitPayload<T> + Send + Sync,
424        T: Send,
425    {
426        let metadata = metadata
427            .with_payload_encoding(C::payload_encoding())
428            .map_err(frame_metadata_error)?;
429        let layout = C::loan_uninit_layout().map_err(UStatus::from)?;
430        let mut buffer = self
431            .loan_uninit_tx(UTxLoanSpec::payload(
432                metadata,
433                layout.len(),
434                layout.align(),
435            )?)
436            .await?;
437        verify_uninit_tx_buffer_payload_layout(&mut buffer, layout.len(), layout.align())?;
438        {
439            let payload = buffer.payload_uninit_mut();
440            // SAFETY: `UZeroCopyUninitTransport::loan_uninit_tx` returned this
441            // buffer as the transport loan for the validated spec. The public
442            // verifier above checked that this visible range matches the request.
443            let loaned = unsafe {
444                LoanedPayloadUninitMut::new_unchecked(
445                    payload,
446                    PayloadLoanProvenance::OpaqueTransportLoan,
447                )
448            };
449            let loaned = C::loan_uninit_payload(loaned).map_err(UStatus::from)?;
450            let expected = loaned.uninit_ptr();
451            let initialized = init(loaned).map_err(UStatus::from)?;
452            if initialized.initialized_ptr().cast::<MaybeUninit<T>>() != expected {
453                return Err(invalid_argument(
454                    "initialized payload proof does not match the TX loan",
455                ));
456            }
457        }
458        // SAFETY: the initializer returned a marker tied to the same checked
459        // loan slot, proving the visible payload bytes have been initialized.
460        let buffer = unsafe { buffer.assume_payload_init() };
461        self.send_zero_copy(buffer).await
462    }
463
464    /// Initializes a stable-container payload through the adapter's selected wire.
465    ///
466    /// Prefer this selected-wire helper on values produced by explicit selected-wire adapter construction.
467    /// It is available only for selected wires whose uninitialized-loan codec is
468    /// `StableContainerPayload<T>`.
469    ///
470    /// # Errors
471    ///
472    /// Returns an error if metadata validation, stable initialization, loaning, or
473    /// send fails.
474    ///
475    #[cfg(feature = "selected-wire-transport-adapter")]
476    async fn send_uninit_stable_payload<T>(
477        &self,
478        metadata: UFrameMetadata,
479        init: impl for<'payload> FnOnce(
480                StablePayloadInitContext<'payload, T>,
481            )
482                -> Result<InitializedStablePayload<'payload, T>, UWireError>
483            + Send,
484    ) -> Result<(), UStatus>
485    where
486        Self: UHasWire,
487        Self::Wire: UWirePayload<T, Codec = StableContainerPayload<T>>,
488        T: StablePayloadInit + Send,
489    {
490        self.send_uninit_stable_payload_as::<T>(metadata, init)
491            .await
492    }
493
494    /// Initializes a stable-container payload directly in uninitialized transmit storage.
495    ///
496    /// This is the low-level stable-container form. Product code that already
497    /// uses explicit selected-wire adapter construction should prefer
498    /// `send_uninit_stable_payload` so
499    /// the selected wire authorizes the stable-container payload family.
500    ///
501    /// The initializer is generated by `#[derive(StablePayloadInit)]`; it exposes
502    /// named typed setters and returns a completion token only after all required
503    /// fields and generated padding gaps are initialized.
504    ///
505    /// # Errors
506    ///
507    /// Returns an error if metadata validation fails, the transport cannot loan
508    /// the requested stable layout, initialization fails, the completion token is
509    /// not completed, or sending the committed loan fails.
510    async fn send_uninit_stable_payload_as<T>(
511        &self,
512        metadata: UFrameMetadata,
513        init: impl for<'payload> FnOnce(
514                StablePayloadInitContext<'payload, T>,
515            )
516                -> Result<InitializedStablePayload<'payload, T>, UWireError>
517            + Send,
518    ) -> Result<(), UStatus>
519    where
520        T: StablePayloadInit + Send,
521    {
522        let metadata = metadata
523            .with_payload_encoding(StableContainerPayload::<T>::encoding())
524            .map_err(frame_metadata_error)?;
525        let layout_len = std::mem::size_of::<T>();
526        let layout_align = std::mem::align_of::<T>();
527        let mut buffer = self
528            .loan_uninit_tx(UTxLoanSpec::payload(metadata, layout_len, layout_align)?)
529            .await?;
530        verify_uninit_tx_buffer_payload_layout(&mut buffer, layout_len, layout_align)?;
531        initialize_stable_tx_payload(&mut buffer, init)?;
532        // SAFETY: the generated stable initializer returned a completion proof
533        // for the same loan slot after all fields and padding were initialized.
534        let buffer = unsafe { buffer.assume_payload_init() };
535        self.send_zero_copy(buffer).await
536    }
537
538    /// Diagnostic variant of [`Self::send_uninit_stable_payload_as`].
539    #[cfg(feature = "perf-diagnostics")]
540    #[doc(hidden)]
541    async fn send_uninit_stable_payload_as_phased<T>(
542        &self,
543        metadata: UFrameMetadata,
544        init: impl for<'payload> FnOnce(
545                StablePayloadInitContext<'payload, T>,
546            )
547                -> Result<InitializedStablePayload<'payload, T>, UWireError>
548            + Send,
549    ) -> Result<UninitStableSendPhases, UStatus>
550    where
551        T: StablePayloadInit + Send,
552    {
553        let total_start = std::time::Instant::now();
554
555        let phase_start = std::time::Instant::now();
556        let metadata = metadata
557            .with_payload_encoding(StableContainerPayload::<T>::encoding())
558            .map_err(frame_metadata_error)?;
559        let layout_len = std::mem::size_of::<T>();
560        let layout_align = std::mem::align_of::<T>();
561        let spec = UTxLoanSpec::payload(metadata, layout_len, layout_align)?;
562        let prepare = phase_start.elapsed();
563
564        let phase_start = std::time::Instant::now();
565        let mut buffer = self.loan_uninit_tx(spec).await?;
566        let loan = phase_start.elapsed();
567
568        let phase_start = std::time::Instant::now();
569        verify_uninit_tx_buffer_payload_layout(&mut buffer, layout_len, layout_align)?;
570        let verify = phase_start.elapsed();
571
572        let phase_start = std::time::Instant::now();
573        initialize_stable_tx_payload(&mut buffer, init)?;
574        let initialize = phase_start.elapsed();
575
576        let phase_start = std::time::Instant::now();
577        // SAFETY: the shared initializer kernel returned a completion proof for
578        // this same verified loan after initializing all fields and padding.
579        let buffer = unsafe { buffer.assume_payload_init() };
580        let witness = phase_start.elapsed();
581
582        let phase_start = std::time::Instant::now();
583        self.send_zero_copy(buffer).await?;
584        let commit = phase_start.elapsed();
585        let total = total_start.elapsed();
586        let accounted = prepare + loan + verify + initialize + witness + commit;
587
588        Ok(UninitStableSendPhases {
589            prepare,
590            loan,
591            verify,
592            initialize,
593            witness,
594            commit,
595            total,
596            residual: total.saturating_sub(accounted),
597        })
598    }
599
600    /// Selected-wire diagnostic variant of [`Self::send_uninit_stable_payload`].
601    #[cfg(all(
602        feature = "perf-diagnostics",
603        feature = "selected-wire-transport-adapter"
604    ))]
605    #[doc(hidden)]
606    async fn send_uninit_stable_payload_phased<T>(
607        &self,
608        metadata: UFrameMetadata,
609        init: impl for<'payload> FnOnce(
610                StablePayloadInitContext<'payload, T>,
611            )
612                -> Result<InitializedStablePayload<'payload, T>, UWireError>
613            + Send,
614    ) -> Result<UninitStableSendPhases, UStatus>
615    where
616        Self: UHasWire,
617        Self::Wire: UWirePayload<T, Codec = StableContainerPayload<T>>,
618        T: StablePayloadInit + Send,
619    {
620        self.send_uninit_stable_payload_as_phased::<T>(metadata, init)
621            .await
622    }
623}
624
625#[cfg(feature = "zero-copy-transport")]
626impl<T> UZeroCopyUninitTransportExt for T where T: UZeroCopyUninitTransport + ?Sized {}
627
628/// *Role: implemented by transports that can lend uninitialized storage — see the [trait map](crate::guide::trait_map).*
629///
630/// Implementation boundary for transports that can expose uninitialized TX payload storage.
631#[async_trait]
632pub trait UZeroCopyUninitTransportImpl: UZeroCopyTransportImpl {
633    /// Transport-specific uninitialized transmit loan type.
634    type UninitTx: UUninitTxBuffer<Initialized = Self::Tx> + Send;
635
636    /// Reserves uninitialized transmit storage for a validated frame loan spec.
637    async fn loan_validated_uninit_tx(&self, spec: UTxLoanSpec) -> Result<Self::UninitTx, UStatus>;
638}
639
640#[cfg(feature = "zero-copy-transport")]
641impl<T> zero_copy_uninit_transport_sealed::Sealed for T where
642    T: UZeroCopyUninitTransportImpl + ?Sized
643{
644}
645
646/// *Role: called by users to obtain uninitialized loans; transports implement [`UZeroCopyUninitTransportImpl`](crate::UZeroCopyUninitTransportImpl) — see the [trait map](crate::guide::trait_map).*
647///
648/// Optional zero-copy capability for transports that can expose uninitialized TX payload storage.
649#[cfg(feature = "zero-copy-transport")]
650#[async_trait]
651pub trait UZeroCopyUninitTransport:
652    UZeroCopyTransport + zero_copy_uninit_transport_sealed::Sealed
653{
654    /// Transport-specific uninitialized transmit loan type.
655    type UninitTx: UUninitTxBuffer<Initialized = Self::Tx> + Send;
656
657    /// Reserves uninitialized transmit storage for a validated frame loan spec.
658    async fn loan_uninit_tx(&self, spec: UTxLoanSpec) -> Result<Self::UninitTx, UStatus>;
659}
660
661#[cfg(feature = "zero-copy-transport")]
662#[async_trait]
663impl<T> UZeroCopyUninitTransport for T
664where
665    T: UZeroCopyUninitTransportImpl + ?Sized,
666{
667    type UninitTx = T::UninitTx;
668
669    async fn loan_uninit_tx(&self, spec: UTxLoanSpec) -> Result<Self::UninitTx, UStatus> {
670        UZeroCopyUninitTransportImpl::loan_validated_uninit_tx(self, spec).await
671    }
672}
673
674#[derive(Clone, Debug, Eq, Hash, PartialEq)]
675struct ZeroCopyListenerRegistrationKey {
676    transport: usize,
677    source_filter: UUri,
678    sink_filter: Option<UUri>,
679    listener: usize,
680}
681
682static ZERO_COPY_LISTENER_REGISTRY: LazyLock<
683    Mutex<HashMap<ZeroCopyListenerRegistrationKey, Arc<dyn Any + Send + Sync>>>,
684> = LazyLock::new(|| Mutex::new(HashMap::new()));
685
686struct ValidatingZeroCopyListener<Rx>
687where
688    Rx: UZeroCopyRxLease + Send + 'static,
689{
690    listener: Arc<dyn UZeroCopyListener<Rx>>,
691}
692
693#[async_trait]
694impl<Rx> UZeroCopyListener<Rx> for ValidatingZeroCopyListener<Rx>
695where
696    Rx: UZeroCopyRxLease + Send + 'static,
697{
698    async fn on_receive_zero_copy(&self, frame: Rx) {
699        match validate_frame_view_for_transport(&frame) {
700            Ok(()) => self.listener.on_receive_zero_copy(frame).await,
701            Err(error) => {
702                warn!(%error, "dropping invalid zero-copy frame before listener delivery")
703            }
704        }
705    }
706}
707
708fn registered_zero_copy_listener<Rx>(
709    key: &ZeroCopyListenerRegistrationKey,
710    listener: Arc<dyn UZeroCopyListener<Rx>>,
711) -> (Arc<dyn UZeroCopyListener<Rx>>, bool)
712where
713    Rx: UZeroCopyRxLease + Send + 'static,
714{
715    let mut registry = ZERO_COPY_LISTENER_REGISTRY
716        .lock()
717        .expect("zero-copy listener registry lock poisoned");
718    if let Some(existing) = registry.get(key) {
719        if let Ok(existing) = existing
720            .clone()
721            .downcast::<ValidatingZeroCopyListener<Rx>>()
722        {
723            let existing: Arc<dyn UZeroCopyListener<Rx>> = existing;
724            return (existing, false);
725        }
726    }
727
728    let validating_listener = Arc::new(ValidatingZeroCopyListener { listener });
729    registry.insert(key.clone(), validating_listener.clone());
730    let validating_listener: Arc<dyn UZeroCopyListener<Rx>> = validating_listener;
731    (validating_listener, true)
732}
733
734fn zero_copy_listener_for_unregister<Rx>(
735    key: &ZeroCopyListenerRegistrationKey,
736    fallback: Arc<dyn UZeroCopyListener<Rx>>,
737) -> Arc<dyn UZeroCopyListener<Rx>>
738where
739    Rx: UZeroCopyRxLease + Send + 'static,
740{
741    ZERO_COPY_LISTENER_REGISTRY
742        .lock()
743        .expect("zero-copy listener registry lock poisoned")
744        .get(key)
745        .and_then(|listener| {
746            listener
747                .clone()
748                .downcast::<ValidatingZeroCopyListener<Rx>>()
749                .ok()
750        })
751        .map_or(fallback, |listener| {
752            listener as Arc<dyn UZeroCopyListener<Rx>>
753        })
754}
755
756fn zero_copy_transport_pointer<T: ?Sized>(transport: &T) -> usize {
757    let ptr = transport as *const T;
758    let thin_ptr = ptr as *const ();
759    thin_ptr as usize
760}
761
762fn zero_copy_listener_pointer<Rx>(listener: &Arc<dyn UZeroCopyListener<Rx>>) -> usize
763where
764    Rx: UZeroCopyRxLease + Send + 'static,
765{
766    let ptr = Arc::as_ptr(listener);
767    let thin_ptr = ptr as *const ();
768    thin_ptr as usize
769}
770
771fn zero_copy_listener_registration_key<T: ?Sized>(
772    transport: &T,
773    source_filter: &UUri,
774    sink_filter: Option<&UUri>,
775    listener: usize,
776) -> ZeroCopyListenerRegistrationKey {
777    ZeroCopyListenerRegistrationKey {
778        transport: zero_copy_transport_pointer(transport),
779        source_filter: source_filter.clone(),
780        sink_filter: sink_filter.cloned(),
781        listener,
782    }
783}
784
785fn verify_zero_copy_filter_criteria(
786    source_filter: &UUri,
787    sink_filter: Option<&UUri>,
788) -> Result<(), UStatus> {
789    verify_filter_criteria(source_filter, sink_filter).map_err(|status| *status)
790}