Fix issue with didOpen processed before initial custom browse config#4846
Fix issue with didOpen processed before initial custom browse config#4846Colengms merged 9 commits intomastermicrosoft/vscode-cpptools:masterfrom coleng/fix_didOpen_before_custom_browsemicrosoft/vscode-cpptools:coleng/fix_didOpen_before_custom_browseCopy head branch name to clipboard
Conversation
| }); | ||
| this.doneInitialCustomBrowseConfigurationCheck = true; | ||
| } | ||
| this.languageClient.sendNotification(ChangeFolderSettingsNotification, params); |
There was a problem hiding this comment.
notifyWhenReady ensures that the languageClient is in a state that it can be used. What mechanism are you putting in place to ensure that you don't crash here?
There was a problem hiding this comment.
It wasn't crashing when I tested it out...was my testing insufficient?
FYI, this fixes the 100% repro of the database clearing with a file open, but I was getting a 2nd harder to repro race condition case still.
There was a problem hiding this comment.
The code in question (sending the initial folder settings) needs to happen before the language client can be used (particularly didOpen needs to be delayed), so this needs to precede anything else that was queued using notifyWhenReady(). When this is called for the first time, it's triggered by the setting of CompilerDefaults, which occurs in a continuation after a prior call to languageClient.sendRequest() (roughly line 817). That would seem to imply it's OK to use languageClient to send messages at that point. All other calls that could wind up here appear to be protected by notifyWhenReady(), or are otherwise only possible if the client is ready. Please let me know if you can identify any cases in which we could wind up here when the client is not ready. Is the client ready at the point in realActivation() where we install callbacks?
There was a problem hiding this comment.
The code has changed a lot since I wrote it, so if you're confident there is no race here, then you can move forward with it. I'm just voicing concerns based on past problems we experienced with crashing while trying to send messages before the language client was ready. As a result, I tried to wrap everything with the *whenReady functions. If this is safe, please add a comment here stating why a *whenReady isn't needed. I used to do periodic checks for sendNotification calls outside of the *whenReady context.
There was a problem hiding this comment.
I have traced all existing calls back to either use of notifyWhenReady, or other evidence that it should be safe (such occurring near the end of the client constructor, where we have an existing call to languageClient.sendRequest. I added use of notifyWhenReady to onDidChangeSettings, as it might be needed there.
There is one remaining code path that I'm having trouble with. In configurations.ts, buildVcpkgIncludePath() is invoking this.handleConfigurationChange() in a finally block. buildVcpkgIncludePath() is called from the constructor of CppProperties. It's unclear to me if it's possible it might (as it's async) trigger a onConfigurationsChanged somewhere in the middle of the onReady() block in the client constructor. But, since all of that is non-async and makes use of languageClient.sendRequest(), it might actually be safe.
…by a config provider other than the currently configured one
…into coleng/fix_didOpen_before_custom_browse
…n config on start-up. Only clear custom browse config when settings are changed to use different config provider.
Should address incomplete fix to #4802
Updates sendCustomBrowseConfiguration to avoid using notifyWhenReady(), in order to ensure the 'last seen' custom browse configuration is delivered on start up before any pending didOpen is processed. The other places this is called are already within a notifyWhenReady().
Fixes an extension ID check to consider
vector-of-bool.cmake-toolsandms-vscode.cmake-toolsto be equivalent.Removed a no longer used arg and related code from notifyWhenReady.