Skip to content

Managed/mount push_data parity + JVM panic-safety fold-ins (chunk #2)#40

Merged
aklofas merged 14 commits into
mainfrom
chunk2-managed-mount-data-push
Jun 14, 2026
Merged

Managed/mount push_data parity + JVM panic-safety fold-ins (chunk #2)#40
aklofas merged 14 commits into
mainfrom
chunk2-managed-mount-data-push

Conversation

@aklofas

@aklofas aklofas commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Chunk #2 of the 4-chunk polish/parity pass (chunk #1 was the JNI panic-safety sweep, #39). Closes the last functional gap from the private-data arc: the ManagedMuxSender (srt auto-reconnect) and MountHandle (rtp RTSP server) shells accepted data-stream configs (W5) but had no push_data/push_data_to, while every other payload kind did. Now closed across C / Python / JVM, mirroring the push_klv family exactly, plus three JVM hardening fold-ins and a CHANGELOG entry for chunk #1.

Waves

  • Core (tst-rtp): MountHandle::push_data / push_data_to / data_handles (mirror push_klv/klv_handles). Updates the tst-rtp cargo public-api baseline (the one non-binding change) + [[exempt]] surface-manifest rows.
  • C (ABI minor 12 → 13): tst_managed_mux_sender_send_data / _to (via with_inner_ref) and tst_rtsp_mount_push_data / _to (ffi_catch + mount_error_to_code); regenerated tstrans.h; 4 abi-rustdoc-coverage allowlist entries. Additive — no symbol removed, no signature/layout change.
  • Python: ManagedMuxSender (srt) + MountHandle (rtp) gain push_data / push_data_to / data_handle() (+ MountHandle.data_handles() list accessor for parity); .pyi stubs + tests (byte-faithful round-trip incl. PTS fidelity over a live SRT loopback).
  • JVM: ManagedMuxSender + MountHandle gain pushData / pushDataTo / dataHandle() (mount also dataHandles()) natives (each in jni_catch) + Java; new *To natives use the strict handle decode. Live-loopback byte-faithful test + forged/negative-handle rejection tests.

JVM fold-ins (W5 follow-ups)

  • Muxer.nPull JNI-bridge failure paths now throw an unchecked RuntimeException (was a checked MuxException), keeping the hot pull() drain method free of a throws clause — matches the W5 nDataHandles precedent.
  • All 16 older handle-targeted *To natives switch the truncating as u32 decode to the strict u32::try_from(...).and_then(try_from_raw) chain (reject out-of-range / negative handles instead of silently truncating).
  • build_muxer_config_from_arrays length-checks the four stream sibling arrays (prevents a panic-across-FFI on a mismatched-array marshalling bug).

CHANGELOG

Drops the "not yet exposed: MountHandle / ManagedMuxSender data push families" caveats in the v0.2.0 [Unreleased] data-stream entries; adds a Changed entry covering chunk #1 panic-safety (JVM panics now surface as RuntimeException instead of aborting the JVM) + these fold-ins.

Verification (all green locally)

fmt; clippy --workspace --all-targets -D warnings; cargo test --workspace both --all-features and --no-default-features (0 failures); cargo public-api clean across all 8 ratcheted crates (tst-rtp baseline updated); #[non_exhaustive] count 265 == BASELINE; all ~44 bash ratchets (incl. jni-catch-coverage, abi-rustdoc-coverage, surface-manifest, header_drift); fuzz check; platform-capabilities. JVM gradle suite + Python pytest green; managed/mount data round-trips byte-faithful.

aklofas added 14 commits June 13, 2026 23:53
…rip test

The data round-trip test referenced a non-existent DemuxEvent.Unknown
variant (the real one is DemuxEvent.UnknownSample), so the consumer
thread died on AttributeError after one event and the assertion only
checked that *some* event flowed — a regression dropping every data
record would still pass. Rework the test to collect the UnknownSample
events on the data PID and assert byte-faithful payload round-trip for
both push_data and push_data_to, plus PTS fidelity (carries_pts=True ⇒
non-zero pushed PTS preserved) and PID/stream_type.

Also fix the close ordering: close the receiver before the sender so
the consumer unblocks via the cancel handle while parked in recv_event,
instead of letting a sender-close break the link and wedge the managed
receiver in a non-cancellable re-accept (which would HANG on a dropped
record rather than fail loud).

Copilot AI left a comment

Copy link
Copy Markdown

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 closes the remaining “private-data stream push” parity gap by adding push_data / push_data_to (and corresponding handle accessors) to the live-shell APIs that previously only accepted data-stream configs: the SRT ManagedMuxSender and RTSP MountHandle. It also folds in several JVM JNI hardening changes (panic/exception behavior, strict handle decoding, and array length validation), and updates ABI/docs/ratchets accordingly.

Changes:

  • Add Rust tst-rtp MountHandle::{push_data,push_data_to,data_handles} plus unit tests and public-api baseline update.
  • Extend C/Python/JVM bindings to expose the same data-push family for managed SRT senders and RTSP mounts; add live-loopback and handle-forgery rejection tests.
  • JVM fold-ins: strict jlongu32 handle decoding for older *To natives, Muxer.nPull JNI-failure paths now throw RuntimeException, and sibling-array length checks in build_muxer_config_from_arrays.

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/coverage/surface-manifest.toml Adds exemptions for new MountHandle data APIs to keep surface coverage ratchets in sync.
scripts/check/c/abi-rustdoc-coverage.sh Allowlists new C ABI symbols for coverage checks.
crates/tst-rtp/src/rtsp/server/mount.rs Implements push_data / push_data_to / data_handles on MountHandle and adds Rust tests.
crates/tst-rtp/public-api.txt Updates public API baseline for the new MountHandle methods.
CHANGELOG.md Updates unreleased notes: removes “not yet exposed” caveats and documents JVM hardening + ABI bump.
bindings/python/tests/test_srt_managed_convenience.py Adds managed SRT loopback fidelity tests for private-data push + handle behavior.
bindings/python/tests/test_rtsp_server.py Adds mount-side data push/handles tests and stats assertions.
bindings/python/src/srt/managed_convenience.rs Exposes ManagedMuxSender.push_data/push_data_to/data_handle in Python.
bindings/python/src/rtp/server.rs Exposes MountHandle.push_data/push_data_to/data_handle/data_handles in Python.
bindings/python/python/tstrans/srt.pyi Updates type stubs for new managed SRT data APIs.
bindings/python/python/tstrans/rtp.pyi Updates type stubs for new mount data APIs.
bindings/jvm/src/test/java/org/tstrans/srt/SrtManagedLiveTest.java Extends live SRT managed test to include private-data round-trip + forged-handle rejection.
bindings/jvm/src/test/java/org/tstrans/rtp/RtspServerTest.java Adds mount data push/stats test and strict-handle-decode regression coverage.
bindings/jvm/src/srt/mux_sender.rs Switches older *To natives to strict handle decode (no truncating as u32).
bindings/jvm/src/srt/managed_convenience.rs Adds managed sender pushData/pushDataTo/dataHandle natives + strict decode.
bindings/jvm/src/rtp/server.rs Adds mount pushData/pushDataTo/dataHandle/dataHandles natives + strict decode.
bindings/jvm/src/rtp/mux_sender.rs Switches older *To natives to strict handle decode.
bindings/jvm/src/mpegts/muxer.rs Adds sibling-array length checks; changes nPull JNI failure paths to RuntimeException.
bindings/jvm/src/main/java/org/tstrans/srt/ManagedMuxSender.java Adds Java surface for pushData/pushDataTo/dataHandle.
bindings/jvm/src/main/java/org/tstrans/rtp/MountHandle.java Adds Java surface for pushData/pushDataTo/dataHandle/dataHandles.
bindings/c/tests/receiving/live_pair.rs Adds managed-sender SRT data-stream live loopback test in C.
bindings/c/include/tstrans.h Bumps ABI minor to 13; adds new managed-sender + mount data push declarations and type placement.
bindings/c/core/src/sender/mux_sender.rs Implements new managed-sender C ABI *_send_data{,_to} entrypoints.
bindings/c/core/src/rtsp/server/mount.rs Implements new mount C ABI *_push_data{,_to} entrypoints + null-handle tests.
bindings/c/core/src/lib.rs Updates ABI minor constant/docs to 13.

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

int64_t pts_90khz);
#endif

#if (defined(TST_HAS_RTP) && defined(TST_HAS_RTP))

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Thanks — correct that the guard is redundant, but this is a pre-existing cbindgen generation artifact, not something this PR introduced. cbindgen ANDs the module-level #[cfg(feature = "rtp")] (the rtsp/rtp modules are gated in lib.rs) with the per-function #[cfg(feature = "rtp")], yielding TST_HAS_RTP && TST_HAS_RTP. It's present on all 83 RTP prototypes (and equivalently on TCP/UDP/RIST — 190 sites total); SRT is the only single-guarded surface because its fns rely solely on the module gate. Since tstrans.h is generated and the header_drift ratchet requires it to match a fresh cbindgen regen exactly, it can't be hand-edited here, and single-guarding only these 2 new mount fns would make the header less uniform. Tracked as a dedicated follow-up: strip the redundant per-function cfgs across all four transport surfaces (matching SRT) + regenerate, with per-feature-mode gating verification, as its own PR. Declining for this PR.

int64_t pts_90khz);
#endif

#if (defined(TST_HAS_RTP) && defined(TST_HAS_RTP))

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Thanks — correct that the guard is redundant, but this is a pre-existing cbindgen generation artifact, not something this PR introduced. cbindgen ANDs the module-level #[cfg(feature = "rtp")] (the rtsp/rtp modules are gated in lib.rs) with the per-function #[cfg(feature = "rtp")], yielding TST_HAS_RTP && TST_HAS_RTP. It's present on all 83 RTP prototypes (and equivalently on TCP/UDP/RIST — 190 sites total); SRT is the only single-guarded surface because its fns rely solely on the module gate. Since tstrans.h is generated and the header_drift ratchet requires it to match a fresh cbindgen regen exactly, it can't be hand-edited here, and single-guarding only these 2 new mount fns would make the header less uniform. Tracked as a dedicated follow-up: strip the redundant per-function cfgs across all four transport surfaces (matching SRT) + regenerate, with per-feature-mode gating verification, as its own PR. Declining for this PR.

@aklofas
aklofas merged commit 0ef5085 into main Jun 14, 2026
26 checks passed
@aklofas
aklofas deleted the chunk2-managed-mount-data-push branch June 14, 2026 18:36
aklofas added a commit that referenced this pull request Jun 15, 2026
Every extern-C fn in the rtp/rtsp/udp/tcp/rist C surfaces carried a
per-function #[cfg(feature = "X")] on top of its already-#[cfg]-gated
module. cbindgen ANDs the module-path cfg with the item cfg, emitting a
redundant `#if (defined(TST_HAS_X) && defined(TST_HAS_X))` double-guard on
190 prototypes in tstrans.h (RTP 83, TCP 39, UDP 34, RIST 34). The SRT and
HLS surfaces never had per-fn cfgs and already produced single guards.

Remove the 190 redundant per-function cfgs (pure deletions; every removed
line exactly duplicated its module's feature — no compound cfg was touched)
and regenerate tstrans.h, collapsing all 190 to `#if defined(TST_HAS_X)`.
The module-level gate in lib.rs remains the sole guard, so symbol gating is
unchanged: verified by nm (--no-default-features exports zero transport
symbols; --features udp exports the 34 udp symbols and no rtp/tcp/rist) and
by compiling all eight feature modes. The committed header's function set
is byte-for-byte identical apart from the guard collapse.

Also refresh the now-stale explanatory comments in
header-conditional-sections.sh, which described the per-fn cfg as the
gating mechanism; the module cfg is.

Resolves the cbindgen double-guard comments raised on PR #40.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants