> How did the other thread get the reference to the object? The only possible existing reference is the one we are using to decrement the shared counter.
I don't think this affects the point you're trying to make, but I suppose you could have three threads, where the logical operations are:
ThreadA:
obj = x->field_a;
ThreadB:
x->field_a = null;
ThreadC:
x->field_b = null;
with both field_a and field_b pointing to the same object initially. It does not affect your point, since ThreadA and ThreadB are now racing.
> Decrementing is done when the reference itself is being dropped (set to null or to point to a different object), which is a logically mutating operation (remember that only the reference count updates are atomic, the operations on the references themselves are not), thus no other acquire operation can be happening concurrently or it would be a data race.
It depends on your programming language. In Java racing on field updates (at the Java level) is well defined (but is allowed to return counter-intuitive results to some degree). That is:
ThreadA
int k = obj.field.hashCode()
ThreadB
obj.field = someOtherValue
is defined and is not allowed to have arbitrarily bad effects like crashing the VM. This is different from C++ (where these kind of accesses are UB, as you seem to imply). Generally, I think for high level languages it is better to have Java-like semantics where even racy accesses have some guarantees.
For C++, I can get the same Java-like guarantees by using `memory_order_relaxed` loads, but I suppose it is defensible for an atomic `shared_ptr` to have a complex refcounting protocol even for `memory_order_relaxed` loads and stores.
> Any concurrent operations on the reference itself must be synchronized via external means, usually a mutex.
Not sure how you're using a reference here, but if by "reference" you mean "a location in the heap" then that does not apply for Java. I personally tend to use "reference" in the same way as "pointer".
> Of course concurrently mutating distinct references which refer to the same object/ref count is fine. edit: rewording
edit: formatting