Guys, I have difficulty in coordinating two threads by using condition variable.
In the example below first thread that is a thread which has the purpose of copying file is supposed to signal with the use of condition variable that it is spawned and it will proceed to copy a file.
There is a thread working for that signal using the same condition variable but unfortunately it seems to me that the copying of a file blocks (strange, it should only block the thread that call is in) until the copying is finished and only after that the signal is received by the waiting thread. Can somebody can look into that and explain to me what I'm doing incorrectly?
Thank you
fn waiting_for_thread_to_start(selected_item: &str, full_dest_path: &str) {
let selected_item_clone = String::from(selected_item);
let full_dest_path_clone = String::from(full_dest_path);
let full_dest_path_clone_2 = String::from(full_dest_path);
let (tx, rx) = std::sync::mpsc::sync_channel(1);
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
// Inside of our lock, spawn a new thread, and then wait for it to start.
thread::spawn(move || {
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
// We notify the condvar that the value has changed.
cvar.notify_one();
match copy_file(&selected_item_clone, &full_dest_path_clone) {
Ok(_) => {
eprintln!("Copied");
tx.send(true);
return;
}
Err(e) => {
eprintln!("couldn't copy: {e}");
tx.send(true);
return;
}
}
});
// Wait for the thread to start up.
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
started = cvar.wait(started).unwrap();
}
println!("Copying thread started (But here we arrive only after copying has been finished). Proceeding to spawn watch thread.");
let _handle_read = std::thread::spawn(move || {
loop {
match rx.try_recv() {
Ok(res) => {
if res {
eprintln!("Received end of copying msg");
break;
}
}
Err(e) => {
eprintln!("Receiving error: {}", e);
}
}
let full_dest_path_clone_2_clone = full_dest_path_clone_2.clone();
match std::fs::File::open(full_dest_path_clone_2_clone) {
Ok(f) => {
let len = f.metadata().unwrap().len();
eprintln!("opened, len: {len}");
}
Err(e) => {
eprintln!("couldn't open: {e}");
}
}
std::thread::sleep(std::time::Duration::from_millis(250));
}
});
}