I reached a strange error while using recursion inside an async.
I can use client
inside the async
. However, if I call do_something
again it complains about std::sync::MutexGuard<'_, Client>
not being send. I think it's trying to send c
to another thread. I thought do_something
executed in a thread, and do_something(client.clone()).await
in another. I don't see why c
is moving from the async
thread to this new thread.
use std::sync::{Arc, Mutex};
use std::future::Future;
use futures::future::{BoxFuture, FutureExt};
struct Client{
}
impl Client {}
fn do_something<'a>(
client: Arc<Mutex<Client>>,
) -> BoxFuture<'a, std::result::Result<(), ()>> {
async move {
let c = client.lock().unwrap();
do_something(client.clone()).await;
Ok(())
}.boxed()
}
fn main() {
let c = Arc::new(Mutex::new(Client{}));
do_something(c.clone());
}
Error:
error: future cannot be sent between threads safely
--> src/main.rs:17:7
|
17 | }.boxed()
| ^^^^^ future created by async block is not `Send`
|
= help: within `impl futures::Future`, the trait `std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, Client>`
note: future is not `Send` as this value is used across an await
--> src/main.rs:15:9
|
14 | let c = client.lock().unwrap();
| - has type `std::sync::MutexGuard<'_, Client>` which is not `Send`
15 | do_something(client.clone()).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `c` maybe used later
16 | Ok(())
17 | }.boxed()
| - `c` is later dropped here