Skip to content
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

vscode rust-analyzer goes to infinite loop #17532

Open
Andrey36652 opened this issue Jul 2, 2024 · 0 comments
Open

vscode rust-analyzer goes to infinite loop #17532

Andrey36652 opened this issue Jul 2, 2024 · 0 comments
Labels
A-chalk chalk related issue C-bug Category: bug

Comments

@Andrey36652
Copy link

rust-analyzer version: 0.4.2021-standalone (1b283db 2024-07-01) (originally found this bug on 0.4.2020)

rustc version: rustc 1.79.0 (129f3b996 2024-06-10)

editor or extension: VSCode, extension version 0.4.2021

rust-analyzer goes to infinite loop maxing one of CPU cores on this program. Types hints (grey font), warning highlights in editor don't work in this state.

use std::sync::{Arc, Mutex, mpsc};
use std::thread;

enum Message<T : Send + 'static> {
    NewJob{
        job: Box<dyn FnOnce() -> T + Send>,
        result_sender: mpsc::Sender<T>,
    },
    Terminate,
}

struct ThreadPool<T : Send + 'static> {
    sender: mpsc::Sender<Message<T>>,
    workers: Vec<thread::JoinHandle<()>>,
}

impl<T : Send + 'static> ThreadPool<T> {
    fn new(n_workers: usize) -> Self {
        assert!(n_workers > 0);

        let (sender, receiver) = mpsc::channel();
        let rcv = Arc::new(Mutex::new(receiver));

        let mut workers = Vec::<thread::JoinHandle<()>>::new();
        workers.reserve(n_workers);

        for _ in 0..n_workers {
            let rcv = Arc::clone(&rcv);
            workers.push(thread::spawn(move || loop {
                let msg = rcv.lock().unwrap().recv().unwrap();
                match msg {
                    Message::NewJob{job, result_sender} => {
                        let result = job();
                        result_sender.send(result).unwrap();
                    },
                    Message::Terminate => break,
                };
            }));
        }

        ThreadPool {
            sender,
            workers
        }
    }

    fn execute<F>(&mut self, f: F) -> mpsc::Receiver<T> where F: FnOnce() -> T + Send +'static {
        let (result_sender, result_receiver) = mpsc::channel();
        self.sender.send(Message::NewJob { job: Box::new(f), result_sender }).unwrap();

        result_receiver
    }

    fn terminate(&mut self) {
        for _ in 0..self.workers.len() {
            self.sender.send(Message::Terminate).unwrap();
        }
    
        for handle in self.workers.drain(..) {
            handle.join().unwrap();
        }
    }
}

fn main() {
    let mut tp = ThreadPool::new(4);

    let mut results_receivers: Vec<mpsc::Receiver<()>> = Vec::new();
    for i in 0..10 {
        let r = tp.execute(move || {
            println!("Task {i} start");
            std::thread::sleep(std::time::Duration::from_millis(2000));
            println!("Task {i} end");
        });
        results_receivers.push(r); // receivers shouldn't die too early
    }

    tp.terminate();
}

However if I comment line result_sender.send(result).unwrap(); and save file - it becomes ok.

Logs are attached in archive
3-Rust Analyzer Language Server.zip

@Andrey36652 Andrey36652 added the C-bug Category: bug label Jul 2, 2024
@Veykril Veykril added the A-chalk chalk related issue label Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-chalk chalk related issue C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

2 participants