-
Notifications
You must be signed in to change notification settings - Fork 460
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
DispatchIO.read spinning while pipe is open on Windows #820
Comments
Tracked in Apple’s issue tracker as rdar://124157417 |
Same problem here. |
To rule out influence of virtual environments like VirtualBox or Parallels, I've tested this on bare metal (3 GHz Intel Core i5-7400, Windows 10): Swift 5.8.1 sourcekit-lsp CPU usage: 0% (the expected behavior) Small note: This time sourcekit-lsp appeared in Task Manager not as a sub-process of Visual Studio Code, but as a separate background process due to some reason. |
Same problem. Running Swift 5.10 directly on Windows 11 x64 |
I have managed to reduce the problem to the following.
Sources/sourcekit-lsp/SourceKitLSP.swift
import Dispatch
import Foundation
#if canImport(CDispatch)
import struct CDispatch.dispatch_fd_t
#endif
@main
struct MyCommand {
static func main() throws {
let fh = try! FileHandle(forWritingTo: URL(fileURLWithPath: #"C:/Users/rintaro/out.txt"#))
try! fh.seekToEnd()
try! fh.write("start\n".data(using: .utf8)!)
let queue: DispatchQueue = DispatchQueue(label: "jsonrpc-queue", qos: .userInitiated)
#if os(Windows)
let rawInFD = dispatch_fd_t(bitPattern: FileHandle.standardInput._handle)
#else
let rawInFD = inFD.fileDescriptor
#endif
let receiveIO = DispatchIO(type: .stream, fileDescriptor: rawInFD, queue: queue) { (error: Int32) in
if error != 0 {
print("IO error \(error)")
}
}
receiveIO.setLimit(lowWater: 1)
receiveIO.read(offset: 0, length: Int.max, queue: queue) { done, data, errorCode in
print("received \(data?.count ?? -1) data")
let fh = try! FileHandle(forWritingTo: URL(fileURLWithPath: #"C:/Users/rintaro/out.txt"#))
try! fh.seekToEnd()
try! fh.write(contentsOf: data!)
}
dispatchMain()
}
}
set SDKROOT=S:\Program Files\Swift\Platforms\Windows.platform\Developer\SDKs\Windows.sdk
path S:\Program Files\Swift\Runtimes\0.0.0\usr\bin;S:\Program Files\Swift\Toolchains\0.0.0+Asserts\usr\bin;%PATH%
"C:\path\to\Microsoft VS Code\Code.exe" C:\path\to\a\swiftpm\project
I was unable to reproduce this issue by launching this modified version of sourcekit-lsp from the command prompt and passing data to stdin by typing or by piping data to the modified version of sourcekit-lsp using Get-Content C:\path\to\input.txt | .\sourcekit-lsp.exe With the following input.txt
|
@tristanlabelle This sounds like a similar issue to swiftlang/sourcekit-lsp#752, which you fixed in #796. Do you have any idea what might be going wrong here? |
That's very interesting, thanks for the reduced repro. It points to another pipe handling problem in libdispatch, likely on the reading side, but I don't know what it may be. What kind of |
I just managed to reduce it even further without any dependency on VS Code. It appears that To reproduce this one:
|
Nice repro @ahoppen ! Let me know if this gets into gnarly libdispatch Win32 pipe semantics and you need help. We're tracking this bug as affecting our developers and we could give a hand to the investigation. |
@tristanlabelle I have reached that stage. If you could investigate it, I would really appreciate it. |
Hi @ahoppen , we'll look into it. Currently our priorities in this area are roughly:
|
It looks like we are spending the time in Edit: Sorry, I just realized that I already reached this debugging state a few months ago. I remembered that you looked into Dispatch before but forgot that the DispatchIO issue was still open. |
@ahoppen I don't remember seeing this before specifically. The trace will be useful though as this is next in the priority list. We got through the file locking issue and I don't think we're hitting the crash anymore (from my list in previous comment). fyi @z2oh |
That would be amazing. I wonder what kind of fix this will be. |
I've figured out what's causing this, but I'm not sure of a proper fix yet. By default, Windows pipes are blocking on both the read and write side ( libdispatch seems to expect non-blocking write semantics on pipes, and so this was effected on Windows in #781 by setting the Perhaps surprisingly, this also changes the read side of the pipe to do non-blocking reads. The original Windows pipe-event implementation (#501) took advantage of Windows' blocking-by-default read semantics and spawned a lightweight thread to call I'm not sure when The comment in the code here seems to indicate that this error implies we have a non-blocking pipe (which is true as we've seen), but I can't intuit why that should cause the loop to restart. Perhaps there was an assumption that the pipe is still initializing and would eventually be set to #781 was cherry-picked into Swift 5.9 (and after), which explains why this issue isn't present in earlier versions. I've built a local |
I've done some more investigation here: The key insight is that the This is to say, I don't see a way to fix this problem without switching back to |
It makes sense to me that a final solution would be with
|
The sourcekit-lsp.exe consumes ~24% of CPU power all the time, even when idle. This bug does not appear under Linux, and does not appear in Swift versions earlier than v5.9. It is still present in v5.10. I tested this under VirtualBox, my virtual machine has 4 virtual processors. The host machine has 13th Gen Intel Core i7 processor, so ~24% load seems like a lot of mysterious calculations.
How to reproduce:
mkdir test
cd test
swift package init
This bug has nothing to do with VS Code. I found this bug when using my own app that runs sourcekit-lsp.exe, and not VS Code.
The text was updated successfully, but these errors were encountered: