The proper logic to add to a cache is
wrlock test if exists again add element unlock
because there is a race condition in the logic below
rdlock
test if the element exists
>> race is here, prior to wrlocking, another thread may wrlock->insert
promote to wrlock
insert
unlock
Wow, how about that. I just (as in within the last hour) read an article in the July issue of DDJ[1] that talked about replacing Singleton (WRowe's second example) with with Double-Checked Locking (WRowe's first example) and the problems that still exist because of compiler optimization.
What it boils down to is if this:
wrlock test if exists again add element unlock
can be broken down as this:
wrlock test if exists again allocate element fill in element insert element unlock
then the compiler may optimize this as:
wrlock test if exists again allocate element insert element >> race is here, prior to filling in element, another thread may >> read element, and use element that hasn't been filled in yet. fill in element unlock
Does the "add element" step guarantee that it won't insert the element into the cache until it is fully constructed, no matter what the optimizer does to the code?
Of course, this is only Part I of the article, Part II isn't until the August issue.
[1] Dr. Dobb's Journal, www.ddj.com (http://www.ddj.com/articles/2004/0407/)