Problems with reading IO without blocking main thread

114 Views Asked by At

I have this code which runs inside impl App and specifically inside fn launch() exactly like this example.

The output reading and writing has to occur in a separate thread so that the GUI doesn't freeze up. I have treid to work with MIO and tokio and subprocesses. With normal threads, I'm having issues with the borrow checker that I'm too much of a noob to solve. Firstly, here is a snippet of the program:

let mut child = Command::new(KOTLINC_PATH)
.arg("-script")
.arg(script_path)
.stdout(Stdio::piped())
// .stderr(Stdio::piped())
.spawn()
.expect("Could not execute script");

std::thread::spawn(move || {
    let out = BufReader::new(
        child.stdout.take().expect("Could not read from stdout."),
    );

    out.lines().for_each(|line| {
        self.output.terminals[0].append(line.unwrap().as_str());
        self.output.terminals[0].append("\n");
    });
});

And here are the errors:

borrowed data escapes outside of associated function
`self` escapes the associated function body here
main.rs(281, 23): `self` is a reference that is only valid in the associated function body
main.rs(281, 19): lifetime `'a` defined here
borrowed data escapes outside of associated function
argument requires that `'a` must outlive `'static`

I've read some articles about using Arc<Mutex<...>> but that requires changing the function signatures and honestly I'm also too much of a noob to figure this out. Would appreciate some help.

Update

let mut child = Command::new(KOTLINC_PATH)
    .args(&["-script", script_path.clone().as_str()])
    .stdout(Stdio::piped())
    .spawn()
    .expect("Could not execute script");

let stdout = child.stdout.take().expect("Could not read from stdout.");

let output_clone = Arc::clone(&output);

let output_thread = thread::spawn(move || {
    let output_clone_ref = &output_clone; // Create a reference to the Arc<Mutex<String>> inside the closure

    for line in BufReader::new(stdout).lines() {
        let output_ref = output_clone_ref.lock().unwrap(); // Acquire a lock on the Mutex to modify the String

        (*output_ref).insert(line.unwrap().as_str());
        (*output_ref).insert("\n");
        drop(output_ref);
    }
});

// Gets stuck here.
output_thread.join().unwrap();
0

There are 0 best solutions below