Borrowed data escapes outside of method

I want to exit Termion's raw mode with drop(stdout) before exiting the process. But I'm doing it inside a spawned thread, and with stdout of type &mut impl Write.

This is a runnable simplified version of the code:

use std::{io::Write, time::Duration};

pub struct CmdRunner {}

impl CmdRunner {
    // there a `new()` method in the original code

    pub fn run(&mut self, stdout: &mut impl Write) {
        // code that runs the command

        let ctrl_c_pressed = false;

        std::thread::spawn(move || {
            if ctrl_c_pressed {
                // I want to use `drop(stdout)` here to exit Termion's raw mode.
                write!(stdout, "Exit raw mode").unwrap();           
                std::process::exit(0);
            }
        });

        std::thread::sleep(Duration::from_secs(5));

        write!(stdout, "Command executed successfully").unwrap();

        stdout.flush().unwrap();
    }
}

fn main() {
    let mut cmd_runner = CmdRunner {};
    let mut stdout = Vec::new();

    cmd_runner.run(&mut stdout);

    println!("stdout: {:?}", String::from_utf8_lossy(&stdout).to_string());
}

This produced this compile error:

impl Write cannot be sent between threads safely
required because it appears within the type &mut impl Write

So I added: pub fn run(&mut self, stdout: &mut (impl Write + std::marker::Send))

But now I'm getting this error:

borrowed data escapes outside of method
stdout escapes the method body here
borrowed data escapes outside of method
argument requires that '1 must outlive 'static

Rust Playground

This is the classic problem with thread::spawn(): the spawned closure can outlive the spawning function (in fact, it might live for an arbitrarily long time, hence it must be 'static). You should use thread::scope() instead: Rust Explorer

1 Like

Please add a link to your original question when you cross-post (to avoid duplicated effort by the community):

I wanted to, but I got this error:

An error occurred: Sorry, new users can only put 2 links in a post.

Thanks! This solution is a lot easier than using Arc<Mutex<_>> (as other person suggested).

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.