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

Unified Diff: net/spdy/spdy_session.cc

Issue 2596703002: http2: Update priorities of pushed streams (Closed)
Patch Set: Created 4 years 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
Index: net/spdy/spdy_session.cc
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index fc549d5af311a4adc4bdfbc04152b4c81558a782..01cb874ac22d502258aa5886c3709c83690dd5c0 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "base/profiler/scoped_tracker.h"
@@ -265,6 +266,20 @@ std::unique_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback(
return std::move(dict);
}
+std::unique_ptr<base::Value> NetLogSpdyPriorityCallback(
+ SpdyStreamId stream_id,
+ SpdyStreamId parent_stream_id,
+ int weight,
+ bool exclusive,
+ NetLogCaptureMode capture_mode) {
+ std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
Bence 2017/01/05 17:14:46 Please use MakeUnique in new code, see https://cs.
Tom Bergan 2017/01/06 00:08:41 Done. Also did a search/replace on the other NetLo
+ dict->SetInteger("stream_id", stream_id);
+ dict->SetInteger("parent_stream_id", parent_stream_id);
+ dict->SetInteger("weight", weight);
+ dict->SetBoolean("exclusive", exclusive);
+ return std::move(dict);
+}
+
// Helper function to return the total size of an array of objects
// with .size() member functions.
template <typename T, size_t N> size_t GetTotalSize(const T (&arr)[N]) {
@@ -772,6 +787,7 @@ bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
}
int SpdySession::GetPushStream(const GURL& url,
+ RequestPriority priority,
base::WeakPtr<SpdyStream>* stream,
const NetLogWithSource& stream_net_log) {
CHECK(!in_io_loop_);
@@ -785,7 +801,26 @@ int SpdySession::GetPushStream(const GURL& url,
if (*stream) {
DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_);
streams_pushed_and_claimed_count_++;
+
+ // If the stream is still open, update its priority to match
+ // the priority of the matching request.
+ if (!(*stream)->IsClosed() && (*stream)->priority() != priority) {
+ (*stream)->set_priority(priority);
+
+ // Send PRIORITY updates.
+ auto updates = priority_dependency_state_.OnStreamUpdate(
+ (*stream)->stream_id(),
+ ConvertRequestPriorityToSpdyPriority(priority));
+ for (auto u : updates) {
+ ActiveStreamMap::iterator it = active_streams_.find(u.id);
+ DCHECK(it != active_streams_.end());
+ int weight = Spdy3PriorityToHttp2Weight(
+ ConvertRequestPriorityToSpdyPriority(it->second->priority()));
+ EnqueuePriorityFrame(u.id, u.dependent_stream_id, weight, u.exclusive);
+ }
+ }
}
+
return OK;
}
@@ -1011,8 +1046,8 @@ std::unique_ptr<SpdySerializedFrame> SpdySession::CreateHeaders(
SpdyStreamId dependent_stream_id = 0;
bool exclusive = false;
- priority_dependency_state_.OnStreamSynSent(stream_id, spdy_priority,
- &dependent_stream_id, &exclusive);
+ priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority,
+ &dependent_stream_id, &exclusive);
if (net_log().IsCapturing()) {
net_log().AddEvent(
@@ -1270,6 +1305,28 @@ void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id,
RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status));
}
+void SpdySession::EnqueuePriorityFrame(SpdyStreamId stream_id,
+ SpdyStreamId dependency_id,
+ int weight,
+ bool exclusive) {
+ net_log().AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_PRIORITY,
+ base::Bind(&NetLogSpdyPriorityCallback, stream_id,
+ dependency_id, weight, exclusive));
+
+ DCHECK(buffered_spdy_framer_.get());
+ std::unique_ptr<SpdySerializedFrame> frame(
+ buffered_spdy_framer_->CreatePriority(stream_id, dependency_id, weight,
+ exclusive));
+
+ // PRIORITY frames describe sequenced updates to the tree, so they must
+ // be serialized. We do this by queueing all PRIORITY frames at HIGHEST
+ // priority.
+ EnqueueWrite(HIGHEST, PRIORITY,
+ base::MakeUnique<SimpleBufferProducer>(
+ base::MakeUnique<SpdyBuffer>(std::move(frame))),
+ base::WeakPtr<SpdyStream>());
+}
+
void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) {
CHECK(!in_io_loop_);
if (availability_state_ == STATE_DRAINING) {
@@ -2408,7 +2465,6 @@ void SpdySession::OnWindowUpdate(SpdyStreamId stream_id,
void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
SpdyStreamId associated_stream_id,
- SpdyPriority priority,
SpdyHeaderBlock headers) {
// Server-initiated streams should have even sequence numbers.
if ((stream_id & 0x1) != 0) {
@@ -2443,8 +2499,8 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
last_accepted_push_stream_id_ = stream_id;
- RequestPriority request_priority =
- ConvertSpdyPriorityToRequestPriority(priority);
+ // Pushed streams are speculative, so they start at an IDLE priority.
+ const RequestPriority request_priority = IDLE;
if (availability_state_ == STATE_GOING_AWAY) {
// TODO(akalin): This behavior isn't in the SPDY spec, although it
@@ -2561,6 +2617,16 @@ void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
stream_max_recv_window_size_, net_log_));
stream->set_stream_id(stream_id);
+ // Convert RequestPriority to a SpdyPriority to send in a PRIORITY frame.
+ SpdyPriority spdy_priority =
+ ConvertRequestPriorityToSpdyPriority(request_priority);
+ SpdyStreamId dependency_id = 0;
+ bool exclusive = false;
+ priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority,
+ &dependency_id, &exclusive);
+ EnqueuePriorityFrame(stream_id, dependency_id,
+ Spdy3PriorityToHttp2Weight(spdy_priority), exclusive);
+
// PUSH_PROMISE arrives on associated stream.
associated_it->second->AddRawReceivedBytes(last_compressed_frame_len_);
last_compressed_frame_len_ = 0;
@@ -2602,8 +2668,7 @@ void SpdySession::OnPushPromise(SpdyStreamId stream_id,
&headers, stream_id, promised_stream_id));
}
- // Any priority will do. TODO(baranovich): Pass parent stream id priority?
- TryCreatePushStream(promised_stream_id, stream_id, 0, std::move(headers));
+ TryCreatePushStream(promised_stream_id, stream_id, std::move(headers));
}
void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id,

Powered by Google App Engine
This is Rietveld 408576698