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 Likes
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);```
1 Like
Trouble is I always get
strong.lock().ok()
| ------ borrow occurs here
83 | }};
| ^ strong
dropped here while still borrowed
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?
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.
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.