-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SR-1639] Move sourcekitdInProc to std::mutex #2793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-1639] Move sourcekitdInProc to std::mutex #2793
Conversation
CC @akyrtzi @benlangmuir Could you review please? |
@swift-ci Please smoke test OS X platform |
Thanks! @benlangmuir and @akyrtzi, I also wrote up some context on all of these SourceKit changes as a comment on https://bugs.swift.org/browse/SR-710 -- hope that helps! |
@modocache this is not deadlocking; what you are seeing is that the sema request - in addition to returning a response - also sends a notification when semantic information is available. More importantly, there is at least one truly asynchronous call to handleRequest, which is cursor-info. So we really do need the semaphore in libsourcekitdInProc. I think a better approach would be to replace that with a more portable primitive like What do you think? |
@benlangmuir Excellent, thanks! I had initially replaced this with a condition variable, but wasn't sure how to make sure it was working. I searched around for something, but didn't find By the way, how do you test that in-proc works? I noticed in-proc is used when building with ASAN... but when testing locally, I usually just comment that condition out. Is there a better way? I'll move this over to |
I don't know that we explicitly test libsourcekitdInProc anywhere 😅. I use it as a debugging aide when there is a crash inside the service and I want to get the backtrace or debug it. We should theoretically re-run the SourceKit tests (or some fast subset of them) in-process, but in practice I don't think I've ever seen a bug that's specific to libsourcekitdInProc. For example the issue you mentioned here is actually not specific to in-process; you can reproduce it with the service by setting |
Great, thanks for working on this! |
b8db620
to
3b8af25
Compare
Awesome, thanks for your help, @benlangmuir! I managed to use The new commit message:
As you mentioned, CI currently doesn't do anything with the in-process code, so CI has no chance of catching any logic errors. I'll trigger a build just to demonstrate it compiles, though. Let me know what you think! @swift-ci Please smoke test OS X platform |
@swift-ci Please smoke test Linux platform |
@modocache does this actually work when handleRequest is synchronous? Conditional variables usually need to be associated with some other variable ("the condition") to handle the case when they are signalled before you start waiting on them. I can't find anything that says C++ condition variable behaves any differently. |
@modocache |
SourceKit's in-process mode uses libdispatch sparingly. Removing all usages of libdispatch would allow SourceKit to more easily be ported to Linux. We can begin this process with the `sourcekitd-test` executable, which makes use of `sourcekitd_send_request_sync`. Migrate this usage to the C++ std::condition_variable.
3b8af25
to
3d6b3ec
Compare
Thanks, @benlangmuir and @gribozavr! I updated the pull request with a condition. This is pretty much the second time I've written C++, and I learned two things:
I think it should work now! I tested it out with both |
|
||
sourcekitd_response_t ReturnedResp; | ||
sourcekitd::handleRequest(req, [&](sourcekitd_response_t resp) { | ||
ReturnedResp = resp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly because of spurious wakeup, this assignment now needs to be atomic or it can race with the read below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The typical pattern is to use the same mutex to protect writing to the condition being waited on.
FYI, @briancroom has apparently met with some success in linking swift-corelibs-libdispatch to SourceKit. That would obviate the need to migrate code like this to I think both @briancroom and I's work is based on #2704, #2763, and #2766, though. If someone could review/merge those first, that'd be great! 🙇 |
Closing this in favor of @briancroom's excellent work. Thanks all! |
What's in this pull request?
SourceKit's in-process mode uses libdispatch sparingly. Removing all usages of libdispatch would allow SourceKit to more easily be ported to Linux. We can begin this process with the
sourcekitd-test
executable, which makes use ofsourcekitd_send_request_sync
.When using an in-process model, sourcekitd::handleRequest is almost always synchronous, so we don't need to wait for the lambda to be executed. The only case in which it is not synchronous is for requests of type "sema", and only when the environment variable 'SOURCEKIT_DELAY_SEMA_EDITOR' is set. However, that feature deadlocks when using an in-process model anyway, so we don't need to worry about it here.
ResolvedRelated bug number: (SR-1639)Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
Validation Testing
Lint Testing
Note: Only members of the Apple organization can trigger swift-ci.