in org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/BeanCache.java [59:107]
public BeanEntry<Q, T> create( final Q qualifier, final Binding<T> binding, final int rank )
{
LazyBeanEntry newBean;
Object o, n;
/*
* Compare-and-swap approach; avoids locking without missing any updates
*/
do
{
o = get();
if ( null == o )
{
// most common case: adding the one (and-only) entry
n = newBean = new LazyBeanEntry( qualifier, binding, rank );
}
else if ( o instanceof LazyBeanEntry )
{
final LazyBeanEntry oldBean = (LazyBeanEntry) o;
if ( binding == oldBean.binding )
{
return oldBean;
}
n = createMap( oldBean, newBean = new LazyBeanEntry( qualifier, binding, rank ) );
}
else
{
synchronized ( this )
{
final Map<Binding, LazyBeanEntry> map = (Map) o;
if ( null == ( newBean = map.get( binding ) ) )
{
map.put( binding, newBean = new LazyBeanEntry( qualifier, binding, rank ) );
mutated = true;
}
return newBean;
}
}
}
while ( !compareAndSet( o, n ) );
if ( n instanceof IdentityHashMap )
{
mutated = true; // entry was upgraded to map, enable readCache
}
return newBean;
}