Lock an Arc+Mutex in one call

so ... is there a way to lock an Arc+Mutex in one call?
i was looking for "inline macros" or "scopeless macros", but no luck

let state_mutex = Arc::clone(&STATE_ARC);
let mut state = state_mutex.lock().unwrap();

state.key = "val";

i have tried ...

macro_rules! lock_mutex_arc {
  ( $mutex_arc:expr ) => {
    {
      let state_mutex = Arc::clone(&$mutex_arc);
      let mut state = state_mutex.lock().unwrap();
      state
      // error[E0597]: `state_mutex` does not live long enough

      $mutex_arc.as_ref().and_then(|mutex| mutex.lock().ok());
      // error[E0599]: no method named `and_then` found for reference `&Mutex<PreloadState>` in the current scope

      let mut state = Arc::clone(&$mutex_arc).lock().unwrap();
      state
      // error[E0716]: temporary value dropped while borrowed

      let mut state = Arc::clone(&$mutex_arc).into_inner().unwrap();
      state
      // error[E0507]: cannot move out of an `Arc`
    }
  };
}

Why not just call .lock().unwrap()? If you really want a macro, try this:

macro_rules! lock_mutex_arc {
  ( $mutex_arc:expr ) => {
    $mutex_arc.lock().unwrap()
  };
}

I have moved your post to a new topic.

this gives a runtime error, my program hangs forever

it works with

let state_mutex = Arc::clone(&STATE_ARC);
let mut state = state_mutex.lock().unwrap();

edit: wait a second ...

These two versions of the code will deadlock in the exact same situations.

Also, based on the name of STATE_ARC, it sounds like it is a global. There's generally no point in putting globals in an Arc, since the entire point of an Arc is to share the value, which the global already takes care of.

the full code looks like share state between hooks · Issue #24 · geofft/redhook · GitHub

it works when STATE_ARC is a Arc<Mutex<HashMap<String, String>>> with

state.insert("x", "y");
state.get("x");

it deadlocks when STATE_ARC is a Arc<Mutex<PreloadState>> with

struct PreloadState {
    map: HashMap<String, String>
}

state.map.insert("x", "y");
state.map.get("x");

looks like, in the second case,
when state leaves the scope, the lock is not released ... ideas?

You can explicitly release the lock with drop(state)

found the bug: i tried to lock the arc/mutex twice in one scope

{
        let mut state = STATE_ARC.lock().unwrap();

        // deadlock
        let mut state = STATE_ARC.lock().unwrap();
}

so, no need for drop(state)

thanks! : )

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.