Race in RCBase::unref
hi -
The code in RCBase::unref() has a dangerous race:
void RCBase::unref () const
{
if (m_count.load()>0) {
m_count--;
if (m_count.load()==0) delete this;
}
}
If the reference count is 2, and two threads simultaneously call unref(), then the count can be decremented twice before either of the comparisons. Then the count==0 comparison will be true in both threads, leading to a double-delete.
The decrement and read for the comparison need to be done as a single atomic operation, for example:
void RCBase::unref () const
{
if (m_count.load()>0) {
unsigned count = --m_count;
if (count==0) delete this;
}
}