Arc::drop
contains this code:
if self.inner().strong.fetch_sub(1, Release) != 1 {
return;
}
Once the current thread (Thread A) has decremented the reference count, Thread B could come in and free the ArcInner
.
The problem becomes apparent when you look at the implementation of fetch_sub
:
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
unsafe { atomic_sub(self.v.get(), val, order) }
// HERE
}
Note the point marked HERE
: at this point we have released our reference, which means that another thread might have freed the ArcInner
. However the &self
still points to the strong reference count in the ArcInner
.