mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
fix deadlock
This commit is contained in:
parent
f48b9d9be7
commit
d9ccebd913
1 changed files with 18 additions and 14 deletions
|
@ -8,7 +8,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use crossbeam_channel::{bounded, after, Sender, Receiver};
|
use crossbeam_channel::{unbounded, after, Sender, Receiver};
|
||||||
use flexi_logger::Logger;
|
use flexi_logger::Logger;
|
||||||
use languageserver_types::{
|
use languageserver_types::{
|
||||||
Url,
|
Url,
|
||||||
|
@ -54,7 +54,6 @@ pub fn project(fixture: &str) -> Server {
|
||||||
buf.push('\n');
|
buf.push('\n');
|
||||||
}
|
}
|
||||||
flush!();
|
flush!();
|
||||||
|
|
||||||
Server::new(tmp_dir, paths)
|
Server::new(tmp_dir, paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +69,8 @@ pub struct Server {
|
||||||
impl Server {
|
impl Server {
|
||||||
fn new(dir: TempDir, files: Vec<(PathBuf, String)>) -> Server {
|
fn new(dir: TempDir, files: Vec<(PathBuf, String)>) -> Server {
|
||||||
let path = dir.path().to_path_buf();
|
let path = dir.path().to_path_buf();
|
||||||
let (client_sender, mut server_receiver) = bounded(1);
|
let (client_sender, mut server_receiver) = unbounded();
|
||||||
let (mut server_sender, client_receiver) = bounded(1);
|
let (mut server_sender, client_receiver) = unbounded();
|
||||||
let server = thread::spawn(move || main_loop(true, path, &mut server_receiver, &mut server_sender));
|
let server = thread::spawn(move || main_loop(true, path, &mut server_receiver, &mut server_sender));
|
||||||
let res = Server {
|
let res = Server {
|
||||||
req_id: Cell::new(1),
|
req_id: Cell::new(1),
|
||||||
|
@ -81,6 +80,7 @@ impl Server {
|
||||||
receiver: client_receiver,
|
receiver: client_receiver,
|
||||||
server: Some(server),
|
server: Some(server),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (path, text) in files {
|
for (path, text) in files {
|
||||||
res.send_notification(RawNotification::new::<DidOpenTextDocument>(
|
res.send_notification(RawNotification::new::<DidOpenTextDocument>(
|
||||||
&DidOpenTextDocumentParams {
|
&DidOpenTextDocumentParams {
|
||||||
|
@ -179,15 +179,11 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn recv(&self) -> Option<RawMessage> {
|
fn recv(&self) -> Option<RawMessage> {
|
||||||
let timeout = Duration::from_secs(5);
|
recv_timeout(&self.receiver)
|
||||||
let msg = select! {
|
.map(|msg| {
|
||||||
recv(&self.receiver, msg) => msg,
|
self.messages.borrow_mut().push(msg.clone());
|
||||||
recv(after(timeout)) => panic!("timed out"),
|
msg
|
||||||
};
|
})
|
||||||
msg.map(|msg| {
|
|
||||||
self.messages.borrow_mut().push(msg.clone());
|
|
||||||
msg
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
fn send_notification(&self, not: RawNotification) {
|
fn send_notification(&self, not: RawNotification) {
|
||||||
self.sender.as_ref()
|
self.sender.as_ref()
|
||||||
|
@ -201,7 +197,7 @@ impl Drop for Server {
|
||||||
{
|
{
|
||||||
self.send_request::<Shutdown>(666, ());
|
self.send_request::<Shutdown>(666, ());
|
||||||
drop(self.sender.take().unwrap());
|
drop(self.sender.take().unwrap());
|
||||||
while let Some(msg) = self.receiver.recv() {
|
while let Some(msg) = recv_timeout(&self.receiver) {
|
||||||
drop(msg);
|
drop(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,3 +206,11 @@ impl Drop for Server {
|
||||||
.join().unwrap().unwrap();
|
.join().unwrap().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn recv_timeout(receiver: &Receiver<RawMessage>) -> Option<RawMessage> {
|
||||||
|
let timeout = Duration::from_secs(5);
|
||||||
|
select! {
|
||||||
|
recv(receiver, msg) => msg,
|
||||||
|
recv(after(timeout)) => panic!("timed out"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue