Skip to content

XERK-2159: Keep a lobby switch made while a stream is starting - #60

Merged
xerhab merged 1 commit into
xerktechfrom
XERK-2159-interpipe
Oct 22, 2026
Merged

xerhab merged 1 commit into
xerktechfrom
XERK-2159-interpipe

Conversation

@xerhab

@xerhab xerhab commented Oct 22, 2026

Copy link
Copy Markdown

Summary: A player switching lobbies while their stream is still starting now gets the lobby's picture and sound, instead of sometimes staying on their own desktop.

Part of XERK-2159

Why

A stream's video and audio consumers are switched from one producer to another when a player joins or leaves a lobby. gst-interpipe decided whether to switch the live listener from GStreamer's "started" flag. That flag is set only after the consumer's own start code returns, and cleared only after its stop code returns. A switch landing in the first gap was only stored, so the consumer stayed on the old producer. A switch in the second gap attached a listener to a stopped consumer. A race rig hit the lost switch 329 times in 2000 starts on the old plugin.

What changed

  • New docker/patches/gst-interpipe-x-listen-to-start-gap.patch: interpipesrc keeps its own started flag, set and cleared under the listeners lock that the switch already takes.
  • New test "A listen-to set while an interpipe consumer starts or stops is kept". It calls the start/stop functions directly to hold each gap open, so it is deterministic.
  • New test "An interpipe producer is unregistered before its pads go". It pins an existing fix (unregistering in dispose); the old stress test caught a regression in only about 1 run in 4.
  • .claude/rules/gst-interpipe.md documents both. It also explains why block=true consumers can hang a producer: that is inherent to block=true, and Wolf's defaults use block=false.

Risk

Low. The patch touches only gst-interpipe's consumer, and reads the new flag under the lock already taken there. It ships with the next image build. Roll back by reverting this commit, which drops the patch.

Testing

QA result: PASS — the patch glob applied to a fresh GST_INTERPIPE_REF checkout; old/new/mutant plugins; race rig; full suite ×3.
Not tested: TSan/ASan/clang CI legs (left to CI); the GStreamer 1.26 image runtime (tested on 1.24.2); a live Moonlight lobby switch.

Test evidence
  • New listen-to test: passes on the patched plugin and fails 3 checks on the old one (testGSTPlugin.cpp gap sections).
  • Dispose-order test: passes on the patched and old plugins, and fails on a mutant that unregisters in finalize (2 == 1).
  • Race rig (live producers; a switch while the consumer goes NULL→PLAYING; 2 cores; 2000 iterations): old plugin 329/2000 lost switches, new plugin 0/2000.
  • [GSTPlugin] ×3, streaming:* / sessions:* / control:* / [GSTREAMER], the full wolftests suite ×3, and 8000 race iterations under a watchdog: no failures, no hangs.

Follow-ups

  • Finding 3 (deadlock with block=true consumers): accepted. I couldn't reproduce it with a rig on the old or new plugin. The producer waiting on a consumer that doesn't drain is what block=true asks for. Documented in the rules file.

interpipesrc decided whether a new listen-to must switch the live listener from
basesrc's started flag, which basesrc sets only after start() returns and clears
only after stop() returns. A listen-to set in the first gap was only stored (the
consumer stayed on the old producer), one in the second listened on a stopped
source. A new gst-interpipe patch tracks started under the listeners lock.

Also pins the teardown patch's dispose ordering with a deterministic test (the
existing stress test caught a regression only ~1 run in 4), and documents why
block=true consumers can hang a producer.
@xerhab
xerhab merged commit 050d620 into xerktech Oct 22, 2026
29 of 32 checks passed
@xerhab
xerhab deleted the XERK-2159-interpipe branch October 22, 2026 16:21
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.

1 participant