public static bool TrySetResult(ref int token, int value) { int oldValue = Volatile.Read(ref token); return(LockState.GetState(oldValue) == LockState.Pending && Interlocked.CompareExchange(ref token, value, oldValue) == oldValue); }
public void Dispose() { if (LockState.GetState(_token) == LockState.Success) { _parent.Release(_token, demandMatch: true); } }
public static ValueTaskSourceStatus GetStatus(ref int token) { return((LockState.GetState(Volatile.Read(ref token))) switch { LockState.Canceled => ValueTaskSourceStatus.Canceled, LockState.Pending => ValueTaskSourceStatus.Pending, _ => ValueTaskSourceStatus.Succeeded, });
private void OnAssignedImpl() // make sure this happens on the { // scheduler's thread to avoid the release thread being stolen var token = LockState.GetResult(ref _token); if (LockState.GetState(token) == LockState.Canceled) { TrySetCanceled(); } else { TrySetResult(new LockToken(_mutex, token)); } }
ValueTaskSourceStatus IValueTaskSource <LockToken> .GetStatus(short key) { switch (LockState.GetState(Volatile.Read(ref _tokens[key]))) { case LockState.Canceled: return(ValueTaskSourceStatus.Canceled); case LockState.Pending: return(ValueTaskSourceStatus.Pending); default: // LockState.Success, LockState.Timeout (we only have 4 bits for status) return(ValueTaskSourceStatus.Succeeded); } }
public static ValueTaskSourceStatus GetStatus(ref int token) { switch (LockState.GetState(Volatile.Read(ref token))) { case LockState.Canceled: return(ValueTaskSourceStatus.Canceled); case LockState.Pending: return(ValueTaskSourceStatus.Pending); default: // LockState.Success, LockState.Timeout (we only have 4 bits for status) return(ValueTaskSourceStatus.Succeeded); } }
public static bool TryCancel(ref int token) { int oldValue; do { // depends on the current state... oldValue = Volatile.Read(ref token); if (LockState.GetState(oldValue) != LockState.Pending) { // already fixed return(false); } // otherwise, attempt to change the field; in case of conflict; re-do from start } while (Interlocked.CompareExchange(ref token, LockState.ChangeState(oldValue, LockState.Canceled), oldValue) != oldValue); return(true); }
public static int GetResult(ref int token) { // if already complete: returns the token; otherwise, dooms the operation int oldValue, newValue; do { oldValue = Volatile.Read(ref token); if (LockState.GetState(oldValue) != LockState.Pending) { // value is already fixed; just return it return(oldValue); } // we don't ever want to report different values from GetResult, so // if you called GetResult prematurely: you doomed it to failure newValue = LockState.ChangeState(oldValue, LockState.Timeout); // if something changed while we were thinking, redo from start } while (Interlocked.CompareExchange(ref token, newValue, oldValue) != oldValue); return(newValue); }
bool IPendingLockToken.HasResult(short key) => LockState.GetState(Volatile.Read(ref _token)) != LockState.Pending;
#pragma warning disable RCS1231 // Make parameter ref read-only. public static bool operator false(LockToken token) => LockState.GetState(token._token) != LockState.Success;