[client] transport: stop after guest sessions end

Track unexpected loss of an admitted fallback independently from normal
stop and UUID revocation. Terminate once both primary and fallback
sessions have disappeared, regardless of notification order.

Make shutdown terminal so concurrent disconnect handling cannot replace
it with restart or running state.
This commit is contained in:
Geoffrey McRae
2026-08-12 12:13:48 +10:00
parent 2d96ec401c
commit 8fb3c4d9f6
7 changed files with 141 additions and 33 deletions

View File

@@ -164,6 +164,16 @@ static void notifyDisconnected(
LG_UNLOCK(fallback->eventLock);
}
static void notifyLost(LG_TransportFallback * fallback, bool requested)
{
if (!requested || !fallback->eventOps.lost)
return;
LG_LOCK(fallback->eventLock);
fallback->eventOps.lost(fallback->eventOpaque);
LG_UNLOCK(fallback->eventLock);
}
static void unpublishProviders(LG_TransportFallback * fallback, bool live)
{
LG_LOCK(fallback->providerLock);
@@ -420,9 +430,12 @@ static bool connectFallback(LG_TransportFallback * fallback)
notifyConnected(fallback);
bool lost = false;
while (!atomic_load_explicit(&fallback->stop, memory_order_acquire))
{
lgWaitEvent(fallback->wakeEvent, SESSION_POLL_MS);
if (atomic_load_explicit(&fallback->stop, memory_order_acquire))
break;
applyVideoRequest(fallback);
LG_LOCK_EXCLUSIVE(fallback->lock);
@@ -436,16 +449,21 @@ static bool connectFallback(LG_TransportFallback * fallback)
if (reject || !admitted || closing)
break;
if (!sessionLive(fallback))
{
lost = !atomic_load_explicit(
&fallback->stop, memory_order_acquire);
break;
}
}
const bool knownDead = !atomic_load_explicit(
&fallback->stop, memory_order_acquire) && !sessionLive(fallback);
const bool reportDisconnect = cleanupConnection(fallback, knownDead);
const bool reportDisconnect = cleanupConnection(fallback, lost);
if (reportMismatch && fallback->eventOps.uuidMismatch)
fallback->eventOps.uuidMismatch(
fallback->eventOpaque, primaryUUID, fallbackUUID);
const bool reportLost = lost && reportDisconnect && !atomic_load_explicit(
&fallback->stop, memory_order_acquire);
notifyLost(fallback, reportLost);
notifyDisconnected(fallback, reportDisconnect);
return true;
}