I have this code:
use std::sync::atomic::{AtomicIsize, Ordering};
#[derive(Default)]
pub struct Worker {
work: Vec<u32>,
progress: AtomicIsize,
}
impl Worker {
fn do_work(&mut self) {
self.work.push(0u32);
self.progress.store(self.progress.load(Ordering::SeqCst) + 1, Ordering::SeqCst);
}
fn get_progress(&self) -> isize {
self.progress.load(Ordering::SeqCst)
}
}
pub struct Manager<CB: FnMut()> {
cb: CB
}
impl<CB: FnMut()> Manager<CB> {
fn do_a_bit_more_work(&mut self) {
(self.cb)();
}
}
fn main() {
let mut worker = Worker::default();
let mut manager = Manager {
cb: || worker.do_work()
};
while worker.get_progress() < 100 {
manager.do_a_bit_more_work();
}
}
That is, I have some manager that calls a callback to do some work. I want the callback to be Worker::do_work()
and that function updates the members of Worker
so it needs &mut self
. However once I pass worker.do_work()
to the manager it means worker
is mutably borrowed so I can never use it again.
I want to use it again to check progress, and maybe change its behaviour. I can use atomic operations and mutexes and so on to try to make sure it is safe to do so, but how can I tell Rust to allow this without getting the cannot borrow X as immutable because it is also borrowed as mutable
error?
I'm guessing it is something to do with Cell
or RefCell
but I can't work it out.