Reputation: 33
The logic of test_use_std_mutex_1
and test_use_std_mutex_2
is the same. Why does one report an error while the other compiles successfully?
fn main() {
let rt = tokio::runtime::Builder::new_multi_thread().worker_threads(2)
.enable_all().build().unwrap();
rt.block_on(async {
let (sen, mut rec) = tokio::sync::mpsc::channel::<()>(1);
// Why can it be compiled by commenting out here? Isn't their logic the same?
tokio::spawn(test_use_std_mutex_1(sen.clone()));
tokio::spawn(test_use_std_mutex_2(sen.clone()));
drop(sen);
let _ = rec.recv().await;
println!("over");
});
}
async fn test_use_std_mutex_1(sen: Sender<()>) {
let _sen = sen;
let mut rwlock_list: Arc<Mutex<LinkedList<String>>> = Default::default();
let mut lock = rwlock_list.lock().unwrap();
println!("push_back hello");
lock.push_back("hello".to_string());
// Is it not deleted here?
drop(lock);
time::sleep(Duration::from_secs(1)).await;
}
async fn test_use_std_mutex_2(sen: Sender<()>) {
let _sen = sen;
let mut rwlock_list: Arc<Mutex<LinkedList<String>>> = Default::default();
{
let mut lock = rwlock_list.lock().unwrap();
println!("push_back hello");
lock.push_back("hello".to_string());
}
time::sleep(Duration::from_secs(1)).await;
}
error: future cannot be sent between threads safely
--> src\main.rs:39:22
|
39 | tokio::spawn(test_use_std_mutex_1(sen.clone()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `test_use_std_mutex_1` is not `Send`
|
= help: within `impl futures_util::Future<Output = ()>`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, LinkedList<std::string::String>>`
note: future is not `Send` as this value is used across an await
--> src\main.rs:55:40
|
50 | let mut lock = rwlock_list.lock().unwrap();
| -------- has type `std::sync::MutexGuard<'_, LinkedList<std::string::String>>` which is not `Send`
...
55 | time::sleep(Duration::from_secs(1)).await;
| ^^^^^^ await occurs here, with `mut lock` maybe used later
56 | }
| - `mut lock` is later dropped here
What is causing this?
Upvotes: 3
Views: 281
Reputation: 71300
This is issue #57478: Dropped variables still included in generator type, or issue #87309: Moved value is considered as held across an await in async fn. Both are part of issue #69663: Tracking issue for more precise generator captures.
This issue is not fixed by using the nightly -Zdrop-tracking
flag. I filled an issue.
Upvotes: 3