changed MultiThreadedRefCounter to use relaxed atomics to increment and decrement the counter. The rationale was that it's "just a counter". But that isn't true; it's a reference counter, which has additional semantics that impose stronger requirements on the atomic operations. In particular, the decrement operation must be a release operation, and must be followed by an acquire barrier when the counter reaches zero. This is needed to ensure any possible accesses in one thread "happen before" deleting the object in a different thread. Without those barriers all kinds of bad data races are possible.