// Queue up a fully rendered frame to send public Task WriteFrameAsync(Frame frame, Priority priority) { PriorityQueueEntry entry = new PriorityQueueEntry(frame, priority); Enqueue(entry); SignalDataAvailable(); return entry.Task; }
// Completes when any frames ahead of it have been processed // TODO: Have this only flush messages from one specific HTTP2Stream public Task FlushAsync(/*int streamId, */ Priority priority) { if (!IsDataAvailable) { return Task.FromResult<object>(null); } PriorityQueueEntry entry = new PriorityQueueEntry(priority); Enqueue(entry); SignalDataAvailable(); return entry.Task; }
public bool TryDequeue(out PriorityQueueEntry entry) { lock (_queueLock) { if (_queue.Count == 0) { entry = null; return false; } entry = _queue.First.Value; _queue.RemoveFirst(); return true; } }
// TODO: How can we make enqueue faster than O(n) and still maintain O(1) dequeue? public void Enqueue(PriorityQueueEntry entry) { lock (_queueLock) { // Scan backwards, so we end up in order behind other items of the same priority. LinkedListNode<PriorityQueueEntry> current = _queue.Last; /* Disabled until it can be refactored. Header frames must never be re-ordered due to compression. while (current != null && current.Value.Priority > entry.Priority) { current = current.Previous; } */ if (current == null) { // New entry is highest priority (the list may be empty). _queue.AddFirst(entry); } else { _queue.AddAfter(current, entry); } } }
// Queue up a fully rendered frame to send public void WriteFrame(Frame frame) { //Do not write to already closed stream if (frame.FrameType != FrameType.Settings && frame.FrameType != FrameType.GoAway && frame.FrameType != FrameType.Ping && _streams[frame.StreamId] == null) { return; } var priority = frame.StreamId != 0 ? _streams[frame.StreamId].Priority : Priority.Pri7; IQueueItem entry; if (IsPriorityTurnedOn) { entry = new PriorityQueueEntry(frame, priority); } else { entry = new QueueEntry(frame); } _messageQueue.Enqueue(entry); }
private bool TryDequeue(out PriorityQueueEntry entry) { return _messageQueue.TryDequeue(out entry); }
private void Enqueue(PriorityQueueEntry entry) { _messageQueue.Enqueue(entry); }