You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.1 KiB
122 lines
3.1 KiB
#if FAT |
|
|
|
using System; |
|
using System.Threading; |
|
using LinqInternal.Threading.Needles; |
|
|
|
namespace LinqInternal.Threading |
|
{ |
|
internal sealed class LockSlot<T> : IComparable<LockSlot<T>>, INeedle<T>, IEquatable<LockSlot<T>> |
|
{ |
|
internal readonly int _id; |
|
private readonly LockContext<T> _context; |
|
private int _free; |
|
private VersionProvider.VersionToken _versionToken; |
|
|
|
internal LockSlot(LockContext<T> context, int id, VersionProvider.VersionToken versionToken) |
|
{ |
|
if (context == null) |
|
{ |
|
throw new ArgumentNullException("context"); |
|
} |
|
_context = context; |
|
_versionToken = versionToken; |
|
_id = id; |
|
} |
|
|
|
bool IReadOnlyNeedle<T>.IsAlive |
|
{ |
|
get { return !ReferenceEquals(Value, null); } |
|
} |
|
|
|
public T Value { get; set; } |
|
|
|
internal bool IsOpen |
|
{ |
|
get { return Volatile.Read(ref _free) == 0; } |
|
} |
|
|
|
public static bool operator !=(LockSlot<T> left, LockSlot<T> right) |
|
{ |
|
if (ReferenceEquals(left, null)) |
|
{ |
|
return !ReferenceEquals(right, null); |
|
} |
|
return !left.Equals(right); |
|
} |
|
|
|
public static bool operator <(LockSlot<T> left, LockSlot<T> right) |
|
{ |
|
if (ReferenceEquals(left, null)) |
|
{ |
|
return true; |
|
} |
|
return left.CompareTo(right) < 0; |
|
} |
|
|
|
public static bool operator ==(LockSlot<T> left, LockSlot<T> right) |
|
{ |
|
if (ReferenceEquals(left, null)) |
|
{ |
|
return ReferenceEquals(right, null); |
|
} |
|
return left.Equals(right); |
|
} |
|
|
|
public static bool operator >(LockSlot<T> left, LockSlot<T> right) |
|
{ |
|
if (ReferenceEquals(left, null)) |
|
{ |
|
return false; |
|
} |
|
return left.CompareTo(right) > 0; |
|
} |
|
|
|
public void Close() |
|
{ |
|
if (Interlocked.CompareExchange(ref _free, 1, 0) == 0) |
|
{ |
|
Value = default(T); |
|
_context.Close(this); |
|
} |
|
} |
|
|
|
public int CompareTo(LockSlot<T> other) |
|
{ |
|
if (ReferenceEquals(other, null)) |
|
{ |
|
return 1; |
|
} |
|
return _versionToken.CompareTo(other._versionToken); |
|
} |
|
|
|
public override bool Equals(object obj) |
|
{ |
|
return obj is LockSlot<T> && Equals((LockSlot<T>)obj); |
|
} |
|
|
|
public bool Equals(LockSlot<T> other) |
|
{ |
|
if (other == null) |
|
{ |
|
return false; |
|
} |
|
return _versionToken.Equals(other._versionToken); |
|
} |
|
|
|
public override int GetHashCode() |
|
{ |
|
return _context.GetHashCode(); |
|
} |
|
|
|
internal void Open(VersionProvider.VersionToken versionToken) |
|
{ |
|
if (Interlocked.CompareExchange(ref _free, 0, 1) == 1) |
|
{ |
|
_versionToken = versionToken; |
|
} |
|
} |
|
} |
|
} |
|
|
|
#endif |