in src/Microsoft.Azure.Relay/Common/InputQueue.cs [378:451]
void EnqueueAndDispatch(Item item, bool canDispatchOnThisThread)
{
bool disposeItem = false;
IQueueReader reader = null;
bool dispatchLater = false;
IQueueWaiter[] waiters;
bool itemAvailable;
lock (ThisLock)
{
itemAvailable = !((queueState == QueueState.Closed) || (queueState == QueueState.Shutdown));
this.GetWaiters(out waiters);
if (queueState == QueueState.Open)
{
if (canDispatchOnThisThread)
{
if (readerQueue.Count == 0)
{
itemQueue.EnqueueAvailableItem(item);
}
else
{
reader = readerQueue.Dequeue();
}
}
else
{
if (readerQueue.Count == 0)
{
itemQueue.EnqueueAvailableItem(item);
}
else
{
itemQueue.EnqueuePendingItem(item);
dispatchLater = true;
}
}
}
else
{
// queueState == QueueState.Closed || queueState == QueueState.Shutdown
disposeItem = true;
}
}
if (waiters != null)
{
if (canDispatchOnThisThread)
{
CompleteWaiters(itemAvailable, waiters);
}
else
{
CompleteWaitersLater(itemAvailable, waiters);
}
}
if (reader != null)
{
InvokeDequeuedCallback(item.DequeuedCallback);
reader.Set(item);
}
if (dispatchLater)
{
ActionItem.Schedule(s => OnDispatchCallback(s), this);
}
else if (disposeItem)
{
InvokeDequeuedCallback(item.DequeuedCallback);
DisposeItem(item);
}
}