I have two structs A and B that need to be able to call each other. A is supposed to be the owner of B, as in, A creates B and calls B.run() to start some concurrent loops. Occasionally, A calls b.start()
to initiate some process in B. Similarly, occasionally, B calls a.append()
to initiate some process in A.
I could get this setup working with the code below. However, is there a better way to structure my code to eliminate the cyclical Arc dependencies?
Link: Rust Playground
use std::sync::{Arc,Mutex};
struct A {
b: Option<Arc<Mutex<B>>>,
}
struct B {
a: Option<Arc<Mutex<A>>>,
}
impl A {
fn start(&self){
println!("start called in A...possibly accessing some fields...");
}
fn trigger(&self) {
let inner_b = self.b.as_ref().unwrap();
let b = inner_b.lock().unwrap();
b.append();
}
}
impl B {
fn append(&self){
println!("append called in B...possibly accessing some fields...");
}
fn trigger(&self) {
let inner_a = self.a.as_ref().unwrap();
let a = inner_a.lock().unwrap();
a.start();
}
}
#[tokio::main]
async fn main(){
let mut a = Arc::new(Mutex::new(A {
b: None,
}));
let mut b = Arc::new(Mutex::new(B {
a: None,
}));
{
let mut a = a.lock().unwrap();
a.b = Some(b.clone());
}
{
let mut b = b.lock().unwrap();
b.a = Some(a.clone());
}
{
let a = a.lock().unwrap();
a.trigger();
}
{
let b = b.lock().unwrap();
b.trigger();
}
}