Hi!
I've made a component similar to sync_channel
where I want to guarantee all messages on the Receiver
side are used before the channel is discarded. The SyncSender
side contains a Weak
which on every .send()
is upgraded to an Arc
.
In this stack trace SyncSender
is my implementation, not std.
pub struct SyncSender<T> {
state: Weak<(Mutex<State<T>>, Condvar)>,
name: String,
}
Occasionally my program crashes with this, and I'm a bit perplexed. I don't have any unsafe code here, and the docs don't mention that upgrade()
has any panic situations.
Are there situations that Weak wrapping a Mutex/Condvar could fail?
* thread #2, name = 'vtc_dec', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
* frame #0: 0x00000001001af6ce umar`core::sync::atomic::atomic_load<usize>(dst=0x646e6553636e7953, order=Relaxed) at atomic.rs:1498
frame #1: 0x00000001001af53c umar`core::sync::atomic::{{impl}}::load(self=0x646e6553636e7953, order=Relaxed) at atomic.rs:1078
frame #2: 0x00000001001ea33d umar`alloc::arc::{{impl}}::upgrade<(std::sync::mutex::Mutex<umar::chan::State<umar::shovel::Parcel<umar::video::Picture>>>, std::sync::condvar::Condvar)>(self=0x0000000107667060) at arc.rs:1039
frame #3: 0x00000001000e1e0d umar`umar::chan::{{impl}}::send<umar::shovel::Parcel<umar::video::Picture>>(self=0x0000000107667060, t=Parcel<umar::video::Picture> @ 0x000070000bf3ddd0) at chan.rs:39
The implementation:
impl<T: Send> SyncSender<T> {
pub fn send(&self, t: T) -> Result<(), SendError<T>> {
match self.state.upgrade() {
Some(state) => {
let &(ref mutex, ref cvar) = &*state;
let mut state = mutex.lock().unwrap();
...