Closures causes self to never be dropped
⚓ Rust 📅 2025-12-06 👤 surdeus 👁️ 3Hi, I'm having a problem with a function from Paho MQTT Rust library which is defined minimally as followed:
// Paho code
impl AsyncClient {
pub fn set_connection_lost_callback(&self, cb: impl FnMut(&Self) + Send + 'static) {
/* Stores the callback and when the client loses connection, it calls it. */
}
}
I'm calling it in the constructor of my struct:
pub struct MyClient {
client: paho::AsyncClient,
}
// Dummy impl
impl Drop for MyClient {
fn drop(&mut self) {
println!("Never prints");
}
}
impl MyClient {
pub fn new() -> Self {
let client: paho::AsyncClient = ...;
let (conn_lost_tx, conn_lost_rx) = async_channel::bounded(1);
client.set_connection_lost_callback(move |_| {
conn_lost_tx.send_blocking(());
});
glib::spawn_future_local(async move {
loop {
let Some(()) = conn_lost_rx.recv().await else {
return;
};
println!("Connection lost");
}
});
Self {
client
}
}
}
When client returned by new is dropped, it doesn't call dummy trait Drop. I tried closing the tx channel, passing weak channel to the callback, none of that works. It only works when the closure captures nothing:
client.set_connection_lost_callback(|_| {}); // Captures nothing
I'm not too much experienced in rust, but I think it has something to do with the closure being 'static and the capture itself capturing the stack memory from new function.
Thanks.
4 posts - 2 participants
🏷️ Rust_feed