private void AsyncUnlink(DListNode waiter)
 {
     lock (_lock)
     {
         DListNode.RemoveIfInserted(waiter);
     }
 }
 private void SyncUnlink(DListNode waiter)
 {
     lock (_lock)
     {
         DListNode.RemoveIfInserted(waiter);
         MonitorEx.PulseAll(_lock, waiter);
     }
 }
        private bool TrySetStateAndRemoveWaiter(Waiter <Data> waiter, int state)
        {
            bool res = waiter.TrySetState(state);

            if (res)
            {
                DListNode.RemoveIfInserted(waiter);
            }
            return(res);
        }
Exemple #4
0
        public void Release()
        {
            Waiter toFinish = null;

            lock (_lock)
            {
                if (currentPermits + 1 > maxPermits)
                {
                    throw new ArgumentOutOfRangeException("releases");
                }
                currentPermits += 1;
                Waiter waiter;
                while ((waiter = (Waiter)DListNode.FirstEntry(waiters)) != null)
                {
                    if (Volatile.Read(ref waiter.state) != WAITING)
                    {
                        DListNode.RemoveIfInserted(waiter);
                        continue;
                    }
                    if (waiter.TrySetState(SUCCESS))
                    {
                        DListNode.RemoveIfInserted(waiter);
                        currentPermits -= 1;
                        toFinish        = waiter;
                        break;
                    }
                }
            }
            // finish it outside the lock
            if (toFinish != null)
            {
                // cancel the active cancelers
                if (toFinish.ctkReg != null)
                {
                    toFinish.ctkReg.Dispose();
                }
                if (toFinish.timer != null)
                {
                    toFinish.timer.Dispose();
                }
                toFinish.tcs.SetResult(true);
            }
        }
Exemple #5
0
        public void OnCancellation(object state)
        {
            var waiter = (Waiter)state;

            if (waiter.TrySetState(CANCELED))
            {
                if (DListNode.IsInList(waiter))
                {
                    lock (_lock)
                    {
                        DListNode.RemoveIfInserted(waiter);
                    }
                }
                if (waiter.timer != null)
                {
                    waiter.timer.Dispose();
                }
                waiter.tcs.SetCanceled();
            }
        }
Exemple #6
0
        public void OnTimeout(object state)
        {
            var waiter = (Waiter)state;

            if (waiter.TrySetState(CANCELED))
            {
                if (DListNode.IsInList(waiter))
                {
                    lock (_lock)
                    {
                        DListNode.RemoveIfInserted(waiter);
                    }
                }
                if (waiter.ctkReg != null)
                {
                    waiter.ctkReg.Dispose();
                }
                waiter.timer.Dispose();
                waiter.tcs.SetResult(false);
            }
        }
        public void Release()
        {
            Waiter <Data> toFinish = null;

            lock (_lock)
            {
                if (currentPermits + 1 > maxPermits)
                {
                    throw new ArgumentOutOfRangeException("releases");
                }
                currentPermits += 1;
                Waiter <Data> waiter;
                while ((waiter = (Waiter <Data>)DListNode.FirstEntry(waiters)) != null)
                {
                    if (Volatile.Read(ref waiter.state) != WaiterState.WAITING)
                    {
                        // Shouldn't already be on the queue, ensure it is removed
                        DListNode.RemoveIfInserted(waiter);
                        continue;
                    }
                    if (waiter.TrySetStateAndUnlink(WaiterState.SUCCESS))
                    {
                        currentPermits -= 1;
                        // queue node for further processing outside the lock
                        waiter.prev = toFinish;
                        toFinish    = waiter;
                        break;
                    }
                }
            }
            // finish the stack of satisfied requests
            while (toFinish != null)
            {
                toFinish.OnSuccess();
                toFinish = (Waiter <Data>)toFinish.prev;
            }
        }