Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(611)

Unified Diff: net/spdy/spdy_session.cc

Issue 1411383005: Initial implementation of RequestPriority-based HTTP/2 dependencies. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Final round of comments. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_pool_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_session.cc
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 80e24c6dd79ebf42ec56f304563a9581be9efe6a..28bab83f51e3b78b0b419be874bcf4d751ad47c8 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -59,6 +59,14 @@ const int kHungIntervalSeconds = 10;
// Minimum seconds that unclaimed pushed streams will be kept in memory.
const int kMinPushedStreamLifetimeSeconds = 300;
+// Field trial constants
+const char kSpdyDependenciesFieldTrial[] = "SpdyEnableDependencies";
+const char kSpdyDepencenciesFieldTrialEnable[] = "Enable";
+
+// Whether the creation of SPDY dependencies based on priority is
+// enabled by default.
+static bool priority_dependency_enabled_default = false;
+
scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue(
const SpdyHeaderBlock& headers,
NetLogCaptureMode capture_mode) {
@@ -691,6 +699,7 @@ SpdySession::SpdySession(
hung_interval_(base::TimeDelta::FromSeconds(kHungIntervalSeconds)),
trusted_spdy_proxy_(trusted_spdy_proxy),
time_func_(time_func),
+ send_priority_dependency_(priority_dependency_enabled_default),
weak_factory_(this) {
DCHECK_GE(protocol_, kProtoSPDYMinimumVersion);
DCHECK_LE(protocol_, kProtoSPDYMaximumVersion);
@@ -700,6 +709,10 @@ SpdySession::SpdySession(
base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair()));
next_unclaimed_push_stream_sweep_time_ = time_func_() +
base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
+ if (base::FieldTrialList::FindFullName(kSpdyDependenciesFieldTrial) ==
+ kSpdyDepencenciesFieldTrialEnable) {
+ send_priority_dependency_ = true;
+ }
// TODO(mbelshe): consider randomization of the stream_hi_water_mark.
}
@@ -1045,6 +1058,11 @@ bool SpdySession::CloseOneIdleConnection() {
return false;
}
+// static
+void SpdySession::SetPriorityDependencyDefaultForTesting(bool enable) {
+ priority_dependency_enabled_default = enable;
+}
+
void SpdySession::EnqueueStreamWrite(
const base::WeakPtr<SpdyStream>& stream,
SpdyFrameType frame_type,
@@ -1085,6 +1103,41 @@ scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
SpdyHeadersIR headers(stream_id);
headers.set_priority(spdy_priority);
headers.set_has_priority(true);
+
+ if (send_priority_dependency_) {
+ // Set dependencies to reflect request priority. A newly created
+ // stream should be dependent on the most recent previously created
+ // stream of the same priority level. The newly created stream
+ // should also have all streams of a lower priority level dependent
+ // on it, which is guaranteed by setting the exclusive bit.
+ //
+ // Note that this depends on stream ids being allocated in a monotonically
+ // increasing fashion, and on all streams in
+ // active_streams_{,by_priority_} having stream ids set.
+ for (int i = priority; i >= IDLE; --i) {
+ if (active_streams_by_priority_[i].empty())
+ continue;
+
+ auto candidate_it = active_streams_by_priority_[i].rbegin();
+
+ // |active_streams_by_priority_| is updated before the
+ // SYN stream frame is created, so the current streams
+ // id is already on the list. Skip over it, skipping this
+ // priority level if it's singular.
+ if (candidate_it->second->stream_id() == stream_id)
+ ++candidate_it;
+ if (candidate_it == active_streams_by_priority_[i].rend())
+ continue;
+
+ headers.set_parent_stream_id(candidate_it->second->stream_id());
+ break;
+ }
+
+ // If there are no streams of priority <= the current stream, the
+ // current stream will default to a child of the idle node (0).
+ headers.set_exclusive(true);
+ }
+
headers.set_fin((flags & CONTROL_FLAG_FIN) != 0);
headers.set_header_block(block);
syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers));
@@ -1291,6 +1344,8 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it,
scoped_ptr<SpdyStream> owned_stream(it->second.stream);
active_streams_.erase(it);
+ active_streams_by_priority_[owned_stream->priority()].erase(
+ owned_stream->stream_id());
// TODO(akalin): When SpdyStream was ref-counted (and
// |unclaimed_pushed_streams_| held scoped_refptr<SpdyStream>), this
@@ -1952,6 +2007,8 @@ void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) {
std::pair<ActiveStreamMap::iterator, bool> result =
active_streams_.insert(
std::make_pair(stream_id, ActiveStreamInfo(stream.get())));
+ active_streams_by_priority_[stream->priority()].insert(
+ std::make_pair(stream_id, stream.get()));
CHECK(result.second);
ignore_result(stream.release());
}
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698