/// <summary>Returns an already completed, new mutex instance</summary> private static AsyncCancelableMutex CreateAlreadyDone() { var mtx = new AsyncCancelableMutex(CancellationToken.None); mtx.Set(async: false); return(mtx); }
/// <summary>Delcare the producer as beeing blocked on a full queue</summary> /// <param name="ct"></param> /// <returns></returns> protected Task MarkProducerAsBlocked_NeedsLocking(CancellationToken ct) { if (ct.IsCancellationRequested) { return(Task.FromCanceled(ct)); } if (m_producerLock.IsCompleted) { m_producerLock = new AsyncCancelableMutex(ct); } LogProducer("blocked on full"); return(m_producerLock.Task); }
private Task WaitForNextItem_NeedsLocking(CancellationToken ct) { if (m_done) { return(Task.CompletedTask); } Contract.Requires(m_blockedConsumer == null || m_blockedConsumer.Task.IsCompleted); var waiter = new AsyncCancelableMutex(ct); m_blockedConsumer = waiter; return(waiter.Task); }
public async Task OnNextAsync(TInput value, CancellationToken ct) { while (!ct.IsCancellationRequested) { AsyncCancelableMutex waiter; lock (m_lock) { if (m_done) { throw new InvalidOperationException("Cannot post more values after calling Complete()"); } if (m_queue.Count < m_capacity) { var t = Task.Factory.StartNew( s_processItemHandler, Tuple.Create(this, value, ct), ct, TaskCreationOptions.PreferFairness, m_scheduler ).Unwrap(); m_queue.Enqueue(t); var _ = t.ContinueWith((_t) => { lock (m_lock) { // we should only wake up the consumers if we are the fist in the queue ! if (m_queue.Count > 0 && m_queue.Peek() == _t) { WakeUpConsumer_NeedLocking(); } } }, TaskContinuationOptions.ExecuteSynchronously); return; } // no luck, we need to wait for the queue to become non-full waiter = new AsyncCancelableMutex(ct); m_blockedProducer = waiter; } await waiter.Task.ConfigureAwait(false); } ct.ThrowIfCancellationRequested(); }
protected Task MarkConsumerAsAwaitingCompletion_NeedsLocking(CancellationToken ct) { Contract.Debug.Requires(m_mode == AsyncOrderingMode.CompletionOrder); var cl = m_completionLock; if (cl.IsCompleted) { LogConsumer("Creating new task completion lock"); cl = new AsyncCancelableMutex(ct); m_completionLock = cl; } LogConsumer("marked as waiting for task completion"); return(cl.Task); }
private static void CancelDefered(AsyncCancelableMutex mutex) { ThreadPool.QueueUserWorkItem((state) => ((AsyncCancelableMutex)state).TrySetCanceled(), mutex); }
private static void SetDefered(AsyncCancelableMutex mutex) { ThreadPool.QueueUserWorkItem((state) => ((AsyncCancelableMutex)state).TrySetResult(null), mutex); }