// 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);
                }
            }
        }
예제 #5
0
        // 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);
 }