Returning from macro rules


#1

How can I write a simple macro rules while returning the value.

ie

macro_rules! unlock_or_none {
         ($var:expr) => {
          
               let strong = $var.upgrade().unwrap();
               strong.lock().ok()
         };
 }

let sender1 = unlock_or_none!(sender);

At the moment I get error: expected expression, found statement (let).

I am using to separate variable as otherwise it gets dropped before the lock.

Thanks


#2

I believe that you need two sets of curly brackets. The outer one are for the macro and the inner ones are retained.

let sender1 = let strong = sender.upgrade().unwrap(); 
strong.lock().ok()

vs.

let sender1 = {
    let strong = sender.upgrade().unwrap(); 
    strong.lock().ok()
}
macro_rules! unlock_or_none {
         ($var:expr) => {{
               let strong = $var.upgrade().unwrap();
               strong.lock().ok()
         }};
 }

let sender1 = unlock_or_none!(sender);```

#3

Trouble is I always get

strong.lock().ok()
| ------ borrow occurs here
83 | }};
| ^ strong dropped here while still borrowed


#4

I’m guessing this is an Arc<Mutex<...>> structure you’re working with, probably the SyncSender stuff we discussed in the other thread?

You can’t “take” a value out of a Mutex that you’ve borrowed - if you could, it defeats the purpose of the Mutex since the value would be unsynchronized.

What are you trying to do here?


#5

Yes

Basically I will be sending Weak<Mutex<SyncSender>> and Weak<Mutex<Receiver>> to lots of functions . That way at shutdown I can drop the strong references and the channels don’t hang. I just wanted a slightly more convenient way of upgrading a unlocking each receiver / sender as I will be doing it hundreds of times.

Not really a big deal. Just using the opportunity to learn a bit more.


#6

Gotcha. Yeah, you’ll need to work with the underlying values via the MutexGuard you get back from lock.

By the way, you shouldn’t need to wrap the SyncSender in a Mutex. The senders are threadsafe and you just clone them and move the clone to your thread. Only the receiver needs protection if you’re going to share it across threads.