embedded-bacnet icon indicating copy to clipboard operation
embedded-bacnet copied to clipboard

Working with the lifetimes on DataLink

Open mnbbrown opened this issue 1 year ago • 7 comments

Caveat: relatively new to rust, familiar with BACnet

Do you have a suggestion for a container that can be used to move DataLink<'a> around with it's underlying buffer safely? For example, consider this task handling incoming datagrams:

let incoming_packet_handler = tokio::spawn({
    // clone Arc<Mutex<HashMap<u8, oneshot::Sender>> of pending confirmed requests
    let pending = pending_transactions.clone();

    async move {
        while let Some(datagram) = rx.recv().await {
            let mut reader = Reader::new_with_len(datagram.len());
            let decoded = DataLink::decode(&mut reader, &datagram);

            match decoded {
                Ok(data_link) => {
                    if let Some(npdu) = data_link.npdu {
                        if let NetworkMessage::Apdu(ApplicationPdu::ComplexAck(ack)) =
                            npdu.network_message
                        {
                            if let Some(tx) = pending.lock().await.remove(&ack.invoke_id) {
                                tx.send(Ok(ack));
                            }
                        }
                    };
                }
                Err(_) => todo!("implement decoding error handling"),
            }
        }
    }
});

It currently fails to compile with "datagram dropped here while still borrowed". This makes sense given the DataLink has borrowed a reference to datagram which is dropped at the end of this context.

Do you have any suggestion on how I might move the ownership of datagram into a container with DataLink to avoid this?

P.S. sorry if some of the ownership nomenclature is wrong..

mnbbrown avatar Jun 30 '24 20:06 mnbbrown