I have a struct that wraps some shared state
struct Demo(Arc<Mutex<State>>);
I would like to return a Result
from a function that spawns a task that indicates if the state was locked or whether the tasked was spawned successfully. What I am trying to do so far
impl Demo {
async fn start(&self) -> Result<(), Busy> {
let local_state = self.0.clone();
if let Ok(state) = local_state.try_lock() {
spawn(async move {
state.some_function().await
});
Ok(())
} else {
Err(Busy)
}
}
}
Which gives
error[E0597]: `local_state` does not live long enough
--> src/lib.rs:19:27
|
18 | let local_state = self.0.clone();
| ----------- binding `local_state` declared here
19 | if let Ok(state) = local_state.try_lock() {
| ^^^^^^^^^^^^^^^^^^^^^^
| |
| borrowed value does not live long enough
| argument requires that `local_state` is borrowed for `'static`
...
27 | }
| - `local_state` dropped here while still borrowed
Which makes sense but I can't figure out how to fix it. Is there a way to allow a locked mutex to be passed to a spawned task? And if not, what would be the best approach to allow the busy state to be returned to the caller?
After reading through the tokio Mutex
docs there is a try_lock_owned
method that the std version doesn't have. This returns an OwnedMutexGuard
that works for this purpose that is only available when the mutex is wrapped in an Arc
.
The working version
impl Demo {
async fn start(&self) -> Result<(), Busy> {
let local_state = self.0.clone();
if let Ok(state) = local_state.try_lock_owned() {
spawn(async move {
state.some_function().await
});
Ok(())
} else {
Err(Busy)
}
}
}