I'm writing a transaction database. The Transaction
struct holds a reference to a MutexGuard
which needs a lifetime annotation, so I have to put a lifetime annotation on the transaction struct. The transaction also has a reference count to the environment struct:
struct Transaction<'a> {
mutex_guard: MutexGuard<'a, i32>,
env: Arc<Env> //I don't know which lifetime annotation to use here for Env.
}
I want the environment to have a weak reference to the write transaction:
struct Env<'a> {
w_txn: Weak<Transaction<'a>>
}
I have to put a lifetime annotation on the Env
struct, which means the environment can't outlive w_txn
, but that's not what I want. I want the environment to always live longer than the transaction, that's why I use Weak
.
So what should I do?
A minimal reproducible example:
use std::sync::{Arc, Mutex, MutexGuard, Weak};
#[derive(Debug)]
struct Env<'a> {
w_txn: Option<Weak<Txn<'a>>>,
}
#[derive(Debug)]
struct Txn<'a> {
env: Arc<Env<'a>>,
mutex_guard: MutexGuard<'a, i32>,
}
impl Txn<'_> {
fn new(env: Arc<Env>, mutex: &Mutex<i32>) -> Arc<Self> {
Arc::new(Self {
env: env.clone(),
mutex_guard: mutex.lock().unwrap(),
})
}
}
fn main() {
let mut env = Arc::new(Env { w_txn: None });
let mut mutex = Mutex::new(0);
let mut txn = Txn::new(env, &mutex);
env.w_txn = Some(Arc::downgrade(&txn));
println!("env: {:?}", env);
println!("txn: {:?}", txn);
}