scaredibis
scaredibis

Reputation: 13

Mutating parent state asynchronously inside of child thread

I have an application that primarily acts as a web server and I am trying to implement a background task that mutates variables from the main thread every second.

The following code snippet has a similar structure to my actual code, this code is inside the main function:

let mut counter: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));

thread::spawn(move || async {
    let mut interval = time::interval(time::Duration::from_secs(1));
    let mut counter_clone = counter.lock().await;
    loop {
        interval.tick().await;
        *counter_clone += 1;
    }
});

The compiler has the following message which does make sense, but what I am trying to do seems like a common problem and I'm hoping someone can offer some guidance.

Compiler error:

async block may outlive the current function, but it borrows `counter`, which is owned by the current function

may outlive borrowed value `counter`

My thinking is that if the main thread dies, the child thread will die anyway.

Any help will be appreciated.

Upvotes: 1

Views: 329

Answers (1)

Netwave
Netwave

Reputation: 42746

Compiler help you:

help: to force the async block to take ownership of `counter` (and any other referenced variables), use the `move` keyword
   |
10 |     thread::spawn(move || async move {
11 |         let mut interval = time::interval(time::Duration::from_secs(1));
12 |         let mut counter_clone = counter.lock().await;
13 |         loop {
14 |             interval.tick().await;
15 |             *counter_clone += 1;
 ...

You need to move it in the async context:

    thread::spawn(|| async move {
        let mut interval = time::interval(time::Duration::from_secs(1));
        let mut counter_clone = counter.lock().await;
        loop {
            interval.tick().await;
            *counter_clone += 1;
        }
    });

Playground

Upvotes: 2

Related Questions