示例#1
0
        /// <summary>
        /// WaitForIdle
        /// </summary>
        /// <param name="ctoken"></param>
        /// <returns></returns>
        public Task WaitForIdle(CancellationToken ctoken)
        {
            if (ctoken.IsCancellationRequested)
            {
                return(Tasks.FromException <bool>(new OperationCanceledException(ctoken)));
            }
            else
            {
                lock (syncRoot) {
                    if (referenceCount == 0)
                    {
                        return(Task.FromResult(true));
                    }
                    else
                    {
                        TaskCompletionSource <bool> k = new TaskCompletionSource <bool>();

                        Waiter waiter = new Waiter()
                        {
                            id     = null,
                            k      = k,
                            ctoken = ctoken,
                            ctr    = null,
                        };

                        long id = waiters.Enqueue(waiter);
                        waiter.id = id;

                        Utils.PostRegistration(ctoken, ctr => SetRegistrationForWait(id, ctr), () => CancelWait(id));

                        return(k.Task);
                    }
                }
            }
        }
示例#2
0
        public Task <Task> StartWorkItem(Func <int, Task> work, CancellationToken ctoken)
        {
            if (ctoken.IsCancellationRequested)
            {
#if NET451
                var tcs = new TaskCompletionSource <Task>();
                tcs.SetException(new OperationCanceledException(ctoken));
                return(tcs.Task);
#else
                return(Task.FromException <Task>(new OperationCanceledException(ctoken)));
#endif
            }
            else
            {
                lock (syncRoot) {
                    if (idleWorkers.Count > 1)
                    {
                        return(Task.FromResult <Task>(StartWorker(work)));
                    }
                    else
                    {
                        TaskCompletionSource <Task> k = new TaskCompletionSource <Task>();

                        WaitingWorkItem wa = new WaitingWorkItem()
                        {
                            id     = null,
                            work   = work,
                            ctoken = ctoken,
                            ctr    = null,
                            k      = k
                        };

                        long id = waitingWorkItems.Enqueue(wa);
                        wa.id = id;

                        Utils.PostRegistration(ctoken, ctr => SetRegistrationForWorkItem(id, ctr), () => CancelWorkItem(id));

                        return(k.Task);
                    }
                }
            }
        }
示例#3
0
        /// <inheritdoc />
        public Task <AcquireWriteResult> AcquireWriteAsync(int desiredSpace, CancellationToken ctoken)
        {
            if (desiredSpace < 1)
            {
                return(Task.FromResult <AcquireWriteResult>(new AcquireWriteFaulted(new ArgumentOutOfRangeException("desiredSpace", "Must be at least one"))));
            }

            if (ctoken.IsCancellationRequested)
            {
                return(Task.FromResult <AcquireWriteResult>(new AcquireWriteCancelled()));
            }
            else
            {
                lock (syncRoot) {
                    if (eofSignaled)
                    {
                        return(Task.FromResult <AcquireWriteResult>(new AcquireWriteFaulted(new InvalidOperationException("Can't acquire for write after EOF has been signaled"))));
                    }
                    else if (!writeLocked.HasValue && (!capacity.HasValue || (capacity.Value - items.Count) >= desiredSpace))
                    {
                        writeLocked = desiredSpace;
                        return(Task.FromResult <AcquireWriteResult>(new AcquireWriteSucceeded(readPtr + items.Count, desiredSpace)));
                    }
                    else if (capacity.HasValue && desiredSpace > capacity.Value)
                    {
                        return(Task.FromResult <AcquireWriteResult>(
                                   new AcquireWriteFaulted(new InvalidOperationException("Attempting to acquire more space than will ever become available"))));
                    }
                    else
                    {
                        TaskCompletionSource <AcquireWriteResult> k = new TaskCompletionSource <AcquireWriteResult>();

                        WaitingWrite ww = new WaitingWrite()
                        {
                            id           = null,
                            desiredSpace = desiredSpace,
                            k            = k,
                            ctr          = null
                        };

                        long id = waitingWrites.Enqueue(ww);
                        ww.id = id;

                        ctoken.PostRegistration(ctr => SetRegistrationForAcquireWrite(id, ctr), () => CancelAcquireWrite(id));

                        return(k.Task);
                    }
                }
            }
        }
示例#4
0
        /// <inheritdoc />
        public Task <AcquireReadResult> AcquireReadAsync(int desiredItems, CancellationToken ctoken)
        {
            if (desiredItems < 1)
            {
                return(Task.FromResult <AcquireReadResult>(new AcquireReadFaulted(new ArgumentOutOfRangeException("desiredItems", "Must be at least one"))));
            }

            if (ctoken.IsCancellationRequested)
            {
                return(Task.FromResult <AcquireReadResult>(new AcquireReadCancelled()));
            }
            else
            {
                lock (syncRoot) {
                    if (!readLocked.HasValue && (items.Count >= desiredItems || eofSignaled))
                    {
                        readLocked = Math.Min(items.Count, desiredItems);
                        return(Task.FromResult <AcquireReadResult>(new AcquireReadSucceeded <T>(readPtr, items.GetRange(0, readLocked.Value))));
                    }
                    else
                    {
                        TaskCompletionSource <AcquireReadResult> k = new TaskCompletionSource <AcquireReadResult>();

                        WaitingRead wr = new WaitingRead()
                        {
                            id           = null,
                            desiredItems = desiredItems,
                            k            = k,
                            ctr          = null,
                        };

                        long id = waitingReads.Enqueue(wr);
                        wr.id = id;

                        ctoken.PostRegistration(ctr => SetRegistrationForAcquireRead(id, ctr), () => CancelAcquireRead(id));

                        return(k.Task);
                    }
                }
            }
        }