|
|
|
@ -57,13 +57,14 @@ namespace Avalonia.Utilities |
|
|
|
var old = _refs; |
|
|
|
while (true) |
|
|
|
{ |
|
|
|
if (old == 0) |
|
|
|
{ |
|
|
|
throw new ObjectDisposedException("Cannot add a reference to a nonreferenced item"); |
|
|
|
} |
|
|
|
var current = Interlocked.CompareExchange(ref _refs, old + 1, old); |
|
|
|
if (current == old) |
|
|
|
{ |
|
|
|
if (current == 0) |
|
|
|
{ |
|
|
|
throw new ObjectDisposedException("Cannot add a reference to a 0-referenced item"); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
old = current; |
|
|
|
} |
|
|
|
@ -78,12 +79,12 @@ namespace Avalonia.Utilities |
|
|
|
|
|
|
|
if (current == old) |
|
|
|
{ |
|
|
|
if (current == 1) |
|
|
|
if (old == 1) |
|
|
|
{ |
|
|
|
_item.Dispose(); |
|
|
|
_item = null; |
|
|
|
} |
|
|
|
return; |
|
|
|
break; |
|
|
|
} |
|
|
|
old = current; |
|
|
|
} |
|
|
|
@ -100,6 +101,7 @@ namespace Avalonia.Utilities |
|
|
|
{ |
|
|
|
_item = item; |
|
|
|
_counter = counter; |
|
|
|
Interlocked.MemoryBarrier(); |
|
|
|
_counter.AddRef(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -148,9 +150,7 @@ namespace Avalonia.Utilities |
|
|
|
{ |
|
|
|
if (_item != null) |
|
|
|
{ |
|
|
|
TResult castItem = null; |
|
|
|
Volatile.Write(ref castItem, (TResult)(object)_item); |
|
|
|
return new Ref<TResult>(castItem, _counter); |
|
|
|
return new Ref<TResult>((TResult)(object)_item, _counter); |
|
|
|
} |
|
|
|
throw new ObjectDisposedException("Ref<" + typeof(T) + ">"); |
|
|
|
} |
|
|
|
|