tokio-rs / website

Website for the Tokio project
https://tokio.rs
MIT License
227 stars 328 forks source link

outdated info in tutorial #766

Closed sineptic closed 1 month ago

sineptic commented 1 month ago

Version rust - 1.80.0-nightly

Platform web

Description in this url: https://tokio.rs/tokio/tutorial/shared-state


Note that this does not work:

use std::sync::{Mutex, MutexGuard};

// This fails too.
async fn increment_and_do_stuff(mutex: &Mutex<i32>) {
    let mut lock: MutexGuard<i32> = mutex.lock().unwrap();
    *lock += 1;
    drop(lock);

    do_something_async().await;
}

This is because the compiler currently calculates whether a future is Send based on scope information only. The compiler will hopefully be updated to support explicitly dropping it in the future, but for now, you must explicitly use a scope.


I tried this code:

use std::{
    sync::{Mutex, MutexGuard},
    thread::sleep,
    time::Duration,
};

async fn do_smth_async() {
    sleep(Duration::from_millis(1000));
}

// This fails too.
async fn increment_and_do_stuff(mutex: &Mutex<i32>) {
    let mut lock: MutexGuard<i32> = mutex.lock().unwrap();
    *lock += 1;
    drop(lock);

    do_smth_async().await;
}

#[tokio::main]
async fn main() {
    let a = Mutex::new(3);
    increment_and_do_stuff(&a).await;
    {
        let a = a.lock().unwrap();
        println!("{a}");
    }
}

I expected to see this happen: compile error

Instead, this happened: all works

Darksonn commented 1 month ago

You will only get an error when it is used from within tokio::spawn. Try wrapping your main function in tokio::spawn.

sineptic commented 1 month ago

you are right