(Though I think Brad is being too pessimistic about volatile. Ensuring release semantics at the store of "singleton" is all you really need - you want to make sure the singleton is fully constructed before you let the world see it. volatile here is overkill.)

Vance's message also slyly introduces the concepts of "acquire" and "release" memory semantics. An interlocked operation with "acquire" semantics prevents future reads from being advanced to before the acquisition. An interlocked operation with "release" semantics prevents previous writes from being delayed until after the release.

In the absence of explicitly-named memory semantics, the Win32 Interlocked* functions by default provide full memory barrier semantics. However, some functions, like InterlockedIncrementAcquire, forego the full memory barrier semantics and provide only acquire or release semantics.

Cool, I was just posting for information. Meyer’s talk was about portable code so what was interesting was the fact so much is left out of the C++ standard. (The paper is on Java but Meyers did a C++ version of the talk).

He actually shows the protocol that has to be followed to get the double checked locking right in the weakest memory model possible (as defined in the C++ standard). I’m glad he did that because otherwise you have to dig that information from comp.programming.threading and it ain’t easy.

Ensuring release semantics at the store of "singleton" is all you really need

You also need an acquire barrier between reading the "ready" flag and reading the data (the Scott Meyers link that Alexei posted mentions that).

I also agree with Meyers that the rule of thumb should be "if you access shared data, protect it with a lock".

It’s only when you discover that locking is a bottleneck that you should start thinking about lock free algorithms, memory barriers etc. (And even then the right solution often is simply to change the design so that you lock less often or don’t hold locks for too long).

I’m surprised to hear that MSDN was promoting double-check-lock as best practice. I recall first hearing about this anti-pattern in Java a few (maybe >= 4) years ago, and then how it was debunked as unsafe. Even after that, it was used in a Sun-supplied solution to the "Question of the Week" on their site (they’ve since fixed it: http://java.sun.com/developer/qow/archive/111/ ).