#if FAT using System; using System.Threading; using LinqInternal.Threading.Needles; namespace LinqInternal.Threading { internal sealed class LockSlot : IComparable>, INeedle, IEquatable> { internal readonly int _id; private readonly LockContext _context; private int _free; private VersionProvider.VersionToken _versionToken; internal LockSlot(LockContext context, int id, VersionProvider.VersionToken versionToken) { if (context == null) { throw new ArgumentNullException("context"); } _context = context; _versionToken = versionToken; _id = id; } bool IReadOnlyNeedle.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 left, LockSlot right) { if (ReferenceEquals(left, null)) { return !ReferenceEquals(right, null); } return !left.Equals(right); } public static bool operator <(LockSlot left, LockSlot right) { if (ReferenceEquals(left, null)) { return true; } return left.CompareTo(right) < 0; } public static bool operator ==(LockSlot left, LockSlot right) { if (ReferenceEquals(left, null)) { return ReferenceEquals(right, null); } return left.Equals(right); } public static bool operator >(LockSlot left, LockSlot 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 other) { if (ReferenceEquals(other, null)) { return 1; } return _versionToken.CompareTo(other._versionToken); } public override bool Equals(object obj) { return obj is LockSlot && Equals((LockSlot)obj); } public bool Equals(LockSlot 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