Async task ( tokio library ) wants to lock a shared data structure used by standard threads

I have the following async task:

let forever = task::spawn(async {
            let mut interval = time::interval(Duration::from_secs(5));

            loop {
                interval.tick().await;
                report_generator::task();
            }
        });

The 'task()' function needs to receive as parameter a reference to a data structure ( an HashMap ) because it needs to write it into a file at regular interval.
The problem is that, the HashMap is used by other threads which are used to fill it so it is used inside a standard Mutex.

So, if i try to write the following code:

let forever = task::spawn(async {
            let mut interval = time::interval(Duration::from_secs(5));
            let mut guard = self.m.lock().unwrap();
            loop {
                interval.tick().await;
                report_generator::task(&guard.map).await;
            }
        });

clearly i get this error : future cannot be sent between threads safely.

How can solve this issue?
Should I implement the Send trait or is there a faster and smarter way?

You need to use Arc to share your HashMap between threads.

Yes, but the problem is that tokio::spawn receives a future and I think the compiler can't infer the lifetime of the guard from an async function.

error: future cannot be sent between threads safely.

I see. Have you looked at Tokio's Mutex? Mutex in tokio::sync - Rust

It's safe to use it within futures.

I had seen them and I could try, but is it advisable to use standard mutexes for standard thread work and tokio mutexes for async work?

You can use them, but you need to take care for non-Send variables not to be alive when calling await. At first sight, your code seems odd, the lock is never released?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.