fix(terminal): clear conn entry before sending exited frame

The exit callback enqueued the exited frame before deleting c.terms[id],
so a client reopening on receipt of exited could hit the open guard while
the entry was still set and have its open dropped. Delete first so the
cleared entry is visible by the time the client sees exited.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Pritom14 2026-05-31 23:09:16 +05:30
parent a766a80f76
commit 4f77062aed
1 changed files with 6 additions and 4 deletions

View File

@ -242,13 +242,15 @@ func (c *connState) openTerminal(_ context.Context, id string) {
})
},
func() {
c.enqueue(serverMsg{Ch: chTerminal, ID: id, Type: msgExited})
// Drop the connection's entry for this id when the pane exits so a
// later open is served instead of being dropped by the open guard.
// markExited fires this without s.mu held, so taking c.mu is safe.
// Clear the connection's entry for this id before sending exited so
// a client that reopens the moment it sees exited finds no stale
// entry and is served instead of dropped by the open guard. Ordering
// the delete after the frame would race that reopen. markExited fires
// this without s.mu held, so taking c.mu is safe.
c.mu.Lock()
delete(c.terms, id)
c.mu.Unlock()
c.enqueue(serverMsg{Ch: chTerminal, ID: id, Type: msgExited})
},
)
// An already-exited session sent its exited frame from subscribe and has