On Monday, 20 May 2013 at 16:40:27 UTC, Dmitry Olshansky wrote:
Long story short - re-read the discussion in the Low-lock thread again:
http://forum.dlang.org/thread/pelhvaxwjzhehdjtp...@forum.dlang.org

To sum up the discussion, there are three problems with unsynchronized access to the __gshared instance reference:

1) Unbaked object - the writer might write the __gshared reference before it finished the construction of the actual object.

2) Non-atomic read/write - this could result in a bad reference where the reader get some bytes from the old reference and some bytes from the new reference.

3) Unsynchronized cache - reader reads the reference, but the part of it's cache that is mapped to the memory containing the object instance itself is out of date and has not received the object yet.

All these problems do not affect `hasInstance()` - which is the only part of my implementation that touches the __gshared reference without synchronization - simply because it does not touch the object and does not return the reference - it only checks if it's initialized:

1) It doesn't matter if the object is not ready, because when you want to actually access the object, you need to use `instance()` which has synchronization.

2) It does not matter if we get half a reference due to non-atomic read/write, because we only care if it's null or not. If the half reference we got is not null, that means the whole reference is not null and we have the correct answer. If the half reference we got is null - well, maybe the other half is not null, but the reference is only now being made not-null, so no harm is done it treating it as null for now(if we actually try to initialize it we will enter synchronization).

3) Since we don't try to access the object itself, we don't care that our local cache doesn't have it yet. Again - once we reach for the object itself, we will enter synchronization.

Reply via email to