mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-28 01:05:01 +03:00
lsp: if language server closes stdout/stderr, break loop (#7229)
Previously we would run these loops indefinitely when a language server closed its stdout/stderr and the `read_until` returned `0` bytes read. Easy to reproduce: start Zed with LSP attached, `kill -9` the LSP, see logs accumulate. Release Notes: - Fix high CPU usage when a language server crashes (or closes its stdout/stderr on purpose). Co-authored-by: Julia <julia@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
944a1f8fb0
commit
3107ed847a
@ -322,8 +322,15 @@ impl LanguageServer {
|
||||
let mut buffer = Vec::new();
|
||||
loop {
|
||||
buffer.clear();
|
||||
stdout.read_until(b'\n', &mut buffer).await?;
|
||||
stdout.read_until(b'\n', &mut buffer).await?;
|
||||
|
||||
if stdout.read_until(b'\n', &mut buffer).await? == 0 {
|
||||
break;
|
||||
};
|
||||
|
||||
if stdout.read_until(b'\n', &mut buffer).await? == 0 {
|
||||
break;
|
||||
};
|
||||
|
||||
let header = std::str::from_utf8(&buffer)?;
|
||||
let message_len: usize = header
|
||||
.strip_prefix(CONTENT_LEN_HEADER)
|
||||
@ -378,6 +385,8 @@ impl LanguageServer {
|
||||
// Don't starve the main thread when receiving lots of messages at once.
|
||||
smol::future::yield_now().await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_stderr<Stderr>(
|
||||
@ -393,7 +402,12 @@ impl LanguageServer {
|
||||
|
||||
loop {
|
||||
buffer.clear();
|
||||
stderr.read_until(b'\n', &mut buffer).await?;
|
||||
|
||||
let bytes_read = stderr.read_until(b'\n', &mut buffer).await?;
|
||||
if bytes_read == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Ok(message) = str::from_utf8(&buffer) {
|
||||
log::trace!("incoming stderr message:{message}");
|
||||
for handler in io_handlers.lock().values_mut() {
|
||||
|
Loading…
Reference in New Issue
Block a user