[client] spice: add fail-fast connection option

This commit is contained in:
Geoffrey McRae
2026-08-16 22:29:20 +10:00
parent 209ac4d749
commit 056be1242a
9 changed files with 54 additions and 16 deletions

View File

@@ -381,14 +381,16 @@ static bool publishConnection(LG_TransportFallback * fallback,
return published;
}
static bool connectFallback(LG_TransportFallback * fallback)
static LG_TransportStatus connectFallback(LG_TransportFallback * fallback,
bool retrying)
{
LG_TransportInstance transport = { 0 };
if (!lgTransport_create(fallback->transportName, &transport))
{
DEBUG_ERROR("Failed to create fallback transport %s",
fallback->transportName);
return false;
if (!retrying)
DEBUG_ERROR("Failed to create fallback transport %s",
fallback->transportName);
return LG_TRANSPORT_ERROR;
}
LG_LOCK_EXCLUSIVE(fallback->lock);
@@ -401,11 +403,12 @@ static bool connectFallback(LG_TransportFallback * fallback)
if (status != LG_TRANSPORT_OK)
{
if (!atomic_load_explicit(&fallback->stop, memory_order_acquire))
if (!retrying && !atomic_load_explicit(
&fallback->stop, memory_order_acquire))
DEBUG_ERROR("Fallback transport %s failed to connect: %d",
fallback->transportName, status);
cleanupConnection(fallback, false);
return false;
return status;
}
LG_LOCK_EXCLUSIVE(fallback->lock);
@@ -445,7 +448,7 @@ static bool connectFallback(LG_TransportFallback * fallback)
if (reportMismatch && fallback->eventOps.endpointMismatch)
fallback->eventOps.endpointMismatch(
fallback->eventOpaque, primaryUUID, fallbackUUID);
return false;
return LG_TRANSPORT_UNAVAILABLE;
}
notifyConnected(fallback);
@@ -483,18 +486,34 @@ static bool connectFallback(LG_TransportFallback * fallback)
fallback->eventOps.endpointMismatch(
fallback->eventOpaque, primaryUUID, fallbackUUID);
notifyDisconnected(fallback, reportDisconnect);
return true;
return lost ? LG_TRANSPORT_DISCONNECTED : LG_TRANSPORT_OK;
}
static int fallbackThread(void * opaque)
{
LG_TransportFallback * fallback = opaque;
unsigned int retry = RETRY_INITIAL_MS;
bool retrying = false;
while (!atomic_load_explicit(&fallback->stop, memory_order_acquire))
{
if (connectFallback(fallback))
const LG_TransportStatus status = connectFallback(fallback, retrying);
if (status == LG_TRANSPORT_OK)
{
retry = RETRY_INITIAL_MS;
retrying = false;
}
else if (status == LG_TRANSPORT_ERROR)
{
if (!atomic_load_explicit(&fallback->stop, memory_order_acquire) &&
fallback->eventOps.connectFailed)
fallback->eventOps.connectFailed(fallback->eventOpaque);
break;
}
else if (status == LG_TRANSPORT_DISCONNECTED)
break;
else
retrying = true;
if (atomic_load_explicit(&fallback->stop, memory_order_acquire))
break;

View File

@@ -2610,6 +2610,13 @@ static void fallbackLost(void * opaque)
app_setState(APP_STATE_SHUTDOWN);
}
static void fallbackConnectFailed(void * opaque)
{
(void)opaque;
DEBUG_INFO("SPICE fallback server is unavailable");
app_setState(APP_STATE_SHUTDOWN);
}
static void fallbackEndpointMismatch(void * opaque, const uint8_t primary[16],
const uint8_t fallback[16])
{
@@ -2624,6 +2631,7 @@ static void fallbackEndpointMismatch(void * opaque, const uint8_t primary[16],
static const LG_TransportFallbackEventOps fallbackEvents =
{
.connected = fallbackConnected,
.connectFailed = fallbackConnectFailed,
.lost = fallbackLost,
.disconnected = fallbackDisconnected,
.videoStateChanged = fallbackVideoStateChanged,

View File

@@ -32,6 +32,8 @@ typedef struct LG_TransportFallbackEventOps
{
/* The session is valid only for the duration of this callback. */
void (*connected)(void * opaque, const LG_TransportSession * session);
/* Called when the fallback transport cannot establish a session. */
void (*connectFailed)(void * opaque);
/* Called only when a usable session is unexpectedly lost. */
void (*lost)(void * opaque);
void (*disconnected)(void * opaque);