Hi, I am trying to use a Mutex inside a Futures (0.3) generator, but I get a compilation error.
Simplified example:
#![feature(futures_api, pin, async_await, await_macro, arbitrary_self_types)]
#![feature(generators)]
use futures::executor::ThreadPool;
use futures::task::SpawnExt;
use futures::channel::oneshot;
use std::sync::Mutex;
async fn my_task() {
let m = Mutex::new(3u32);
let m_guard = m.lock();
let (sender, receiver) = oneshot::channel::<()>();
sender.send(());
await!(receiver);
}
fn main() {
let mut thread_pool = ThreadPool::new().unwrap();
thread_pool.spawn(my_task());
}
Compilation error:
$ cargo run
Compiling check_futures_mutex_guard v0.1.0 (/home/real/temp/check_futures_mutex_guard)
error[E0277]: `std::sync::MutexGuard<'_, u32>` cannot be sent between threads safely
--> src/main.rs:19:17
|
19 | thread_pool.spawn(my_task());
| ^^^^^ `std::sync::MutexGuard<'_, u32>` cannot be sent between threads safely
|
= help: within `impl core::future::future::Future`, the trait `for<'r> std::marker::Send` is not implemented for `std::sync::MutexGuard<'_, u32>`
= note: required because it appears within the type `std::result::Result<std::sync::MutexGuard<'_, u32>, std::sync::PoisonError<std::sync::MutexGuard<'_, u32>>>`
= note: required because it appears within the type `for<'r, 's> {std::sync::Mutex<u32>, std::result::Result<std::sync::MutexGuard<'r, u32>, std::sync::PoisonError<std::sync::MutexGuard<'s, u32>>>, futures_channel::oneshot::Sender<()>, futures_channel::oneshot::Receiver<()>, ()}`
= note: required because it appears within the type `[static generator@src/main.rs:9:20: 15:2 for<'r, 's> {std::sync::Mutex<u32>, std::result::Result<std::sync::MutexGuard<'r, u32>, std::sync::PoisonError<std::sync::MutexGuard<'s, u32>>>, futures_channel::oneshot::Sender<()>, futures_channel::oneshot::Receiver<()>, ()}]`
= note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:9:20: 15:2 for<'r, 's> {std::sync::Mutex<u32>, std::result::Result<std::sync::MutexGuard<'r, u32>, std::sync::PoisonError<std::sync::MutexGuard<'s, u32>>>, futures_channel::oneshot::Sender<()>, futures_channel::oneshot::Receiver<()>, ()}]>`
= note: required because it appears within the type `impl core::future::future::Future`
= note: required because it appears within the type `impl core::future::future::Future`
Note that if I remove the lines:
let (sender, receiver) = oneshot::channel::<()>();
sender.send(());
await!(receiver);
I get no compilation error.
rustc version:
$ rustc --version
rustc 1.31.0-nightly (bef62ccdd 2018-10-16)
I understand that I can not send a MutexGuard
, but I think that in my code I do not actually send it anywhere. It stays inside the generator for the whole time. Any ideas how to solve this are appreciated!
My Cargo.toml:
[package]
name = "check_futures_mutex_guard"
version = "0.1.0"
authors = ["real"]
edition = "2018"
[dependencies]
futures-preview = { version = "0.3.0-alpha.9" }