This is an archive of the discontinued LLVM Phabricator instance.

[clangd] New ParsingCallback for semantics changes
ClosedPublic

Authored by kadircet on May 19 2021, 4:56 AM.

Details

Summary

Previously notification of the Server about semantic happened strictly
before notification of the AST thread.
Hence a racy Server could make a request (like semantic tokens) after
the notification, with the assumption that it'll be served fresh
content. But it wasn't true if AST thread wasn't notified about the
change yet.

This change reverses the order of those notifications to prevent racy
interactions.

Diff Detail

Event Timeline

kadircet created this revision.May 19 2021, 4:56 AM
kadircet requested review of this revision.May 19 2021, 4:56 AM
kadircet edited reviewers, added: hokein; removed: adamcz.
sammccall accepted this revision.May 25 2021, 2:39 AM

It seems like a lit test for this would be terrible. A ClangdServer one should be possible, but I can't quite wrap my head around how to write it.

(Delivering the PreambleData as a param would make the test easier, you could assert that the preamble version was > any previously notified preamble & also > any preamble previously obtained via runWithPreamble.)

clang-tools-extra/clangd/TUScheduler.h
175

This seems a little vague/abstract for TUScheduler.
The "caller" (i.e. ClangdServer impl) needs to know about preambles etc, c.f. onPreambleAST in this same interface.

I'd suggest onPreambleActive or onPreamblePublished or something like that.
(Passing the PreambleData struct as a param would also hint nicely at the distinction vs onPreambleAST but is maybe too cute if we're not actually going to use it...)

This revision is now accepted and ready to land.May 25 2021, 2:39 AM
kadircet updated this revision to Diff 347621.May 25 2021, 3:33 AM
kadircet marked an inline comment as done.
  • s/onSemanticsMaybeChanged/onPreamblePublished

It seems like a lit test for this would be terrible. A ClangdServer one should be possible, but I can't quite wrap my head around how to write it.
(Delivering the PreambleData as a param would make the test easier, you could assert that the preamble version was > any previously notified preamble & also > any preamble previously obtained via runWithPreamble.)

I also put some thought into it, but couldn't figure out a way that wouldn't be flaky. we can write a test that might catch a regression, but it won't catch all of them for sure unless we somehow block the execution of threads.
I tried to find some locking solution that wouldn't depend too much on the TUScheduler's implementation details but couldn't find any, and eventually gave up :/.

I can include a test that ensures runWithAST always sees a new preamble after onPreamblePublished, but as mentioned it is going to be a flaky at best. WDYT?

clang-tools-extra/clangd/TUScheduler.h
175

going with onPreamblePublished, since Active might mean it wasn't previously before (e.g. first preamble for a TU).

This revision was automatically updated to reflect the committed changes.