Skip to content

vscode rust-analyzer goes to infinite loopΒ #17532

Open
@Andrey36652

Description

@Andrey36652

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-chalkchalk related issueC-bugCategory: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions