So here's what we're trying to do:
// -- snip --
tokio::spawn(async move {
if let Error(e) = merkle_blockmap_readback(handle, con, act) {
eprintln!("Ledger failure: {}", e);
}
})
Here's what merkle_blockmap_readback
looks like:
pub async fn merkle_blockmap_readback(handle: &BlockWriter, con: &mut Connection, act: BlockMapArray)
-> Result<(), Box<dyn Error>> {
let howmany = act.howmany();
if howmany == 0 {
return con.write_peer(precompiledresp::Failed).await;
}
// write_peer is almost like TcpStream.write(&[..]).await
con.write_peer(&[b'$', b'1']).await?;
let mut keys = act.into_iter();
// acquire_read returns a read lock from `parking_lot::RwLock`
let rhandle = handle.acquire_read(); // Get a read lock
while let Some(key) = keys.next() {
if let Some(value) = rhandle.get(&key) {
let sig_wback = relayer::sig_wback(value);
con.write_peer(sig_wback).await?;
} else {
// Something wrong with genesis sig
con.write_peer(precompiledresp::BlockSigNotFound).await?;
}
}
Ok(())
}
The trouble that we've run into is with the closure becoming non-Send
, because of the read handle which returns a read lock from parking_lot::RwLock
.
Edit
More precisely, this is the error that we get:
| let rhandle = handle.acquire_read();
| ------ has type `lock_api::rwlock::RwLockReadGuard<'_, parking_lot::raw_rwlock::RawRwLock, blocktables::BlockMapTable>` which is not `Send`
...
| con.write_peer(sig_wback).await?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rhandle` maybe used later
What's the resolution here?