// Must be called with HandlesLock held. // This process the top-level InProgressHandles queue, demuxing entries into the per-instance queues and completing markers. void ProcessInProgressHandles(ref List <InstanceHandleReference> handlesPendingResolution) { while (InProgressHandles.Count > 0) { InstanceHandleReference handleRef = InProgressHandles.Peek(); if (handleRef.InstanceHandle != null) { if (handleRef.InstanceHandle.Id == Guid.Empty) { break; } Queue <InstanceHandleReference> acceptingQueue; if (!InProgressHandlesPerInstance.TryGetValue(handleRef.InstanceHandle.Id, out acceptingQueue)) { if (CheckOldestReference(handleRef, ref handlesPendingResolution)) { acceptingQueue = new Queue <InstanceHandleReference>(2); acceptingQueue.Enqueue(handleRef); InProgressHandlesPerInstance.Add(handleRef.InstanceHandle.Id, acceptingQueue); } } else { // It's ok to enqueue first, then dequeue, to err on the side of duplicates. Duplicates do not cause a problem. acceptingQueue.Enqueue(handleRef); } } InProgressHandles.Dequeue(); } }
// Must be called with HandlesLock held. private void EnqueueReference(InstanceHandleReference handleRef) { if (InProgressHandles.Count > 0) { InProgressHandles.Enqueue(handleRef); } else if (handleRef.InstanceHandle.Id != Guid.Empty) { if (!InProgressHandlesPerInstance.TryGetValue(handleRef.InstanceHandle.Id, out Queue <InstanceHandleReference> queue)) { queue = new Queue <InstanceHandleReference>(2); InProgressHandlesPerInstance.Add(handleRef.InstanceHandle.Id, queue); } queue.Enqueue(handleRef); } else { InProgressHandles.Enqueue(handleRef); } }