/// <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); } } } }
private void CheckWaitingWrites() { if (!writeLocked.HasValue && waitingWrites.Count > 0) { WaitingWrite ww = waitingWrites.Peek(); System.Diagnostics.Debug.Assert(capacity.HasValue, "If there is no capacity limit, there should never be any waiting writes"); // ReSharper disable once PossibleInvalidOperationException if (capacity.Value - items.Count >= ww.desiredSpace) { waitingWrites.Dequeue(); writeLocked = ww.desiredSpace; ww.k.PostResult(new AcquireWriteSucceeded(readPtr + items.Count, ww.desiredSpace)); if (ww.ctr.HasValue) { ww.ctr.Value.PostDispose(); } } } }