1
// Copyright 2011 Google Inc.
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
15
#ifndef MOD_SPDY_COMMON_SPDY_FRAME_PRIORITY_QUEUE_H_
16
#define MOD_SPDY_COMMON_SPDY_FRAME_PRIORITY_QUEUE_H_
21
#include "base/basictypes.h"
22
#include "base/synchronization/condition_variable.h"
23
#include "base/synchronization/lock.h"
25
namespace base { class TimeDelta; }
27
namespace net { class SpdyFrame; }
31
// A priority queue of SPDY frames, intended for multiplexing output frames
32
// from multiple SPDY stream threads back to the SPDY connection thread and
33
// allowing frames from high-priority streams to cut in front of lower-priority
34
// streams. This class is thread-safe -- its methods may be called
35
// concurrently by multiple threads.
36
class SpdyFramePriorityQueue {
38
// Create an initially-empty queue.
39
SpdyFramePriorityQueue();
40
~SpdyFramePriorityQueue();
42
// Return true if the queue is currently empty. (Of course, there's no
43
// guarantee that another thread won't change that as soon as this method
47
// A priority value that is more important than any priority normally used
48
// for sending SPDY frames.
49
static const int kTopPriority;
51
// Insert a frame into the queue at the specified priority. The queue takes
52
// ownership of the frame, and will delete it if the queue is deleted before
53
// the frame is removed from the queue by the Pop method. Note that smaller
54
// numbers indicate higher priorities.
55
void Insert(int priority, net::SpdyFrame* frame);
57
// Remove and provide a frame from the queue and return true, or return false
58
// if the queue is empty. The caller gains ownership of the provided frame
59
// object. This method will try to yield higher-priority frames before
60
// lower-priority ones (even if they were inserted later), but guarantees to
61
// return same-priority frames in the same order they were inserted (FIFO).
62
// In particular, this means that a sequence of frames from the same SPDY
63
// stream will stay in order (assuming they were all inserted with the same
64
// priority -- that of the stream).
65
bool Pop(net::SpdyFrame** frame);
67
// Like Pop(), but if the queue is empty this method will block for up to
68
// max_time before returning false.
69
bool BlockingPop(const base::TimeDelta& max_time, net::SpdyFrame** frame);
72
// Same as Pop(), but requires lock_ to be held.
73
bool InternalPop(net::SpdyFrame** frame);
75
mutable base::Lock lock_;
76
base::ConditionVariable condvar_;
77
// We use a map of lists to store frames, to guarantee that frames of the
78
// same priority are stored in FIFO order. A simpler implementation would be
79
// to just use a multimap, which in practice is nearly always implemented
80
// with the FIFO behavior that we want, but the spec doesn't actually
81
// guarantee that behavior.
83
// Each list stores frames of a particular priority. Invariant: the lists in
84
// the QueueMap are never empty; if one of the lists becomes empty, that
85
// key/value pair is immediately removed from the map.
86
typedef std::list<net::SpdyFrame*> FrameList;
87
typedef std::map<int, FrameList*> QueueMap;
90
DISALLOW_COPY_AND_ASSIGN(SpdyFramePriorityQueue);
93
} // namespace mod_spdy
95
#endif // MOD_SPDY_COMMON_SPDY_FRAME_PRIORITY_QUEUE_H_