• [client, proxy] cancel context before stopping engine on embedded client (#6397)
    Some checks failed
    Release / FreeBSD Port / Build & Test (push) Has been cancelled
    Release / release (push) Has been cancelled
    Release / release_ui (push) Has been cancelled
    Release / release_ui_darwin (push) Has been cancelled
    Release / Windows Installer / Build Test (amd64, amd64) (push) Has been cancelled
    Release / Windows Installer / Build Test (arm64, arm64) (push) Has been cancelled
    Release / Comment release artifacts (push) Has been cancelled
    Release / trigger_signer (push) Has been cancelled
    sync tag / trigger_sync_tag (push) Has been cancelled
    sync tag / trigger_android_bump (push) Has been cancelled
    sync tag / trigger_ios_bump (push) Has been cancelled
    update docs / trigger_docs_api_update (push) Has been cancelled

    rainysy released this 2026-06-11 03:26:54 +08:00

    • Engine.Start takes syncMsgMux with a deferred unlock (engine.go:445) and parks in receiveSignalEvents → WaitStreamConnected (engine.go:1762), which only wakes on
      signal-stream connect or client-context cancellation.
    • When signal never connects, the 30s startup timeout fires and embed.Client.Start's rollback (embed.go:281) called client.Stop() → Engine.Stop, which blocks acquiring
      syncMsgMux (engine.go:318). The cancel() that would unpark Start was deferred until Start returned — permanent cycle. RemovePeer calls (g43/g385) then queue behind the
      lifecycle mutex.
    • Notably, embed.Client.Stop and the daemon's cleanupConnection both cancel before stopping — the startup rollback was the only path that didn't.
    • Engine.Start takes syncMsgMux with a deferred unlock (engine.go:445) and parks in receiveSignalEvents → WaitStreamConnected (engine.go:1762), which only wakes on
      signal-stream connect or client-context cancellation.
    • When signal never connects, the 30s startup timeout fires and embed.Client.Start's rollback (embed.go:281) called client.Stop() → Engine.Stop, which blocks acquiring
      syncMsgMux (engine.go:318). The cancel() that would unpark Start was deferred until Start returned — permanent cycle. RemovePeer calls (g43/g385) then queue behind the
      lifecycle mutex.
    • Notably, embed.Client.Stop and the daemon's cleanupConnection both cancel before stopping — the startup rollback was the only path that didn't.
    Downloads