A Thrift language server, formatter, and linter.
lsp linter helix vim vscode thrift

lsp: fix snapshot swap race, view races, and the shared walk guard master

View.FileChange swapped the snapshot without holding snapshotMu while Snapshot() reads it under the lock: two concurrent FileChanges (the workspace walk plus request handlers, all async) could release the same snapshot twice, panicking the server with a negative WaitGroup counter. The swap, the old snapshot's release, and the release assignment now happen under snapshotMu, and the parse loop and dependent computation run against the snapshot this call created instead of re-reading the (likely newer) view snapshot. IncludeGraph.Get returned live nodes after dropping the RLock; Set and removeWithoutLock mutate those slices in place, racing every reader (Dependents, TokensForFile, referenceFiles). Get now returns a copy. Session.CreateView appended to s.views without viewMu, racing AddView, ViewOf and RemoveView, and duplicated views for the same folder. It is gone; openFile uses AddView. The workspace walk (Initialized) and the per-directory walk (first didOpen) shared one once-guard, so a didOpen racing the Initialized notification permanently skipped scanning the workspace folders. Each walk now has its own sync.Once on the Server. ParsedFile.Tokens lazy-init now uses sync.Once like its siblings, and the no-op Snapshot.Initialize (spawned with ceremony in NewView) is deleted.


Author karitham Date Commit 6205e0e4 Parent 77ffbfe3 Change ID tvtlqqkw