jonhoo / rust-ibverbs

Bindings for RDMA ibverbs through rdma-core

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 :)