Some question for the meaning of designing 3 lifetime of cq, pd and qp
victoryang00 opened this issue · comments
I'm writing some IBStream like below
pub struct IBStream<'a> {
qp: Arc<ibverbs::QueuePair<'a>>,
cq: Arc<ibverbs::CompletionQueue<'a>>,
mr: ibverbs::MemoryRegion<RdmaPrimitive>,
pd: Arc<ibverbs::ProtectionDomain<'a>>,
ctx: Arc<ibverbs::Context>,
}
and if I want to write the new
func:
pub fn new<'b, A: ToSocketAddrs>(addr: A) -> Result<IBStream<'b>, IBError> {
let ctx = Self::setup_ctx()?;
let ctxr: & _ = &ctx;
let cq = Self::setup_cq(ctxr)?;
let pd = Self::setup_pd(&ctx.clone())?;
let qp = Self::setup_qp(&cq.clone(), &pd.clone(), &ctx.clone())?;
let mr = pd.allocate::<RdmaPrimitive>(2).unwrap();
Ok(IBStream {
qp,
cq,
mr,
pd,
ctx,
})
}
The lifetime of ctx is in accordance with the whole struct and could not specify any lifetime hint to make it happen. But if I roll back to this version and remove the lifetime, the code compiled nice and sound. If I have to keep using the latest version, I have to take the ctx out of IBStream.
Yeah, this won't quite work unfortunately as it's basically a self-referential struct. Think about what happens when an IBStream
is dropped — if the ctx
is dropped first, then dropping the other fields would be really bad. You can work around this with something like the ouroboros
. So this is definitely working as intended :)