Index: net/spdy/spdy_session.h |
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h |
index 2975203f433dfe45c08b3f566108e069889b9df5..3d95101fcedd5cb5b66ec5ee6f83b1a5739708a0 100644 |
--- a/net/spdy/spdy_session.h |
+++ b/net/spdy/spdy_session.h |
@@ -19,6 +19,7 @@ |
#include "net/base/load_states.h" |
#include "net/base/net_errors.h" |
#include "net/base/request_priority.h" |
+#include "net/base/ssl_client_cert_type.h" |
#include "net/base/ssl_config_service.h" |
#include "net/base/upload_data_stream.h" |
#include "net/socket/client_socket_handle.h" |
@@ -93,6 +94,32 @@ COMPILE_ASSERT(PROTOCOL_ERROR_UNEXPECTED_PING == |
class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
public BufferedSpdyFramerVisitorInterface { |
public: |
+ // Defines an interface for producing SpdyIOBuffers. |
+ class NET_EXPORT_PRIVATE SpdyIOBufferProducer { |
+ public: |
+ SpdyIOBufferProducer() {} |
+ |
+ // Returns a newly created SpdyIOBuffer, owned by the caller, or NULL |
+ // if not buffer is ready to be produced. |
+ virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) = 0; |
+ |
+ virtual RequestPriority GetPriority() const = 0; |
+ |
+ virtual ~SpdyIOBufferProducer() {} |
+ |
+ protected: |
+ // Activates |spdy_stream| in |spdy_session|. |
+ static void ActivateStream(SpdySession* spdy_session, |
+ SpdyStream* spdy_stream); |
+ |
+ static SpdyIOBuffer* CreateIOBuffer(SpdyFrame* frame, |
+ RequestPriority priority, |
+ SpdyStream* spdy_stream); |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(SpdyIOBufferProducer); |
+ }; |
+ |
// Create a new SpdySession. |
// |host_port_proxy_pair| is the host/port that this session connects to, and |
// the proxy configuration settings that it's using. |
@@ -157,9 +184,14 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
// authentication now. |
bool VerifyDomainAuthentication(const std::string& domain); |
+ // Records that |stream| has a write available from |producer|. |
+ // |producer| will be owned by this SpdySession. |
+ void SetStreamHasWriteAvailable(SpdyStream* stream, |
+ SpdyIOBufferProducer* producer); |
+ |
// Send the SYN frame for |stream_id|. This also sends PING message to check |
// the status of the connection. |
- int WriteSynStream( |
+ SpdySynStreamControlFrame* CreateSynStream( |
SpdyStreamId stream_id, |
RequestPriority priority, |
uint8 credential_slot, |
@@ -167,21 +199,24 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
const SpdyHeaderBlock& headers); |
// Write a CREDENTIAL frame to the session. |
- int WriteCredentialFrame(const std::string& origin, |
- SSLClientCertType type, |
- const std::string& key, |
- const std::string& cert, |
- RequestPriority priority); |
+ SpdyCredentialControlFrame* CreateCredentialFrame(const std::string& origin, |
+ SSLClientCertType type, |
+ const std::string& key, |
+ const std::string& cert, |
+ RequestPriority priority); |
// Write a data frame to the stream. |
// Used to create and queue a data frame for the given stream. |
- int WriteStreamData(SpdyStreamId stream_id, net::IOBuffer* data, |
- int len, |
- SpdyDataFlags flags); |
+ SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id, |
+ net::IOBuffer* data, int len, |
+ SpdyDataFlags flags); |
// Close a stream. |
void CloseStream(SpdyStreamId stream_id, int status); |
+ // Close a stream that has been created but is not yet active. |
+ void CloseCreatedStream(SpdyStream* stream, int status); |
+ |
// Reset a stream by sending a RST_STREAM frame with given status code. |
// Also closes the stream. Was not piggybacked to CloseStream since not |
// all of the calls to CloseStream necessitate sending a RST_STREAM. |
@@ -268,7 +303,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
// Returns true if session is not currently active |
bool is_active() const { |
- return !active_streams_.empty(); |
+ return !active_streams_.empty() || !created_streams_.empty(); |
} |
// Access to the number of active and pending streams. These are primarily |
@@ -277,6 +312,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
size_t num_unclaimed_pushed_streams() const { |
return unclaimed_pushed_streams_.size(); |
} |
+ size_t num_created_streams() const { return created_streams_.size(); } |
// Returns true if flow control is enabled for the session. |
bool is_flow_control_enabled() const { |
@@ -356,6 +392,19 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> > PushedStreamMap; |
typedef std::priority_queue<SpdyIOBuffer> OutputQueue; |
+ typedef std::set<scoped_refptr<SpdyStream> > CreatedStreamSet; |
+ typedef std::map<SpdyIOBufferProducer*, SpdyStream*> StreamProducerMap; |
+ class SpdyIOBufferProducerCompare { |
+ public: |
+ bool operator() (const SpdyIOBufferProducer* lhs, |
+ const SpdyIOBufferProducer* rhs) const { |
+ return lhs->GetPriority() < rhs->GetPriority(); |
+ } |
+ }; |
+ typedef std::priority_queue<SpdyIOBufferProducer*, |
+ std::vector<SpdyIOBufferProducer*>, |
+ SpdyIOBufferProducerCompare> WriteQueue; |
+ |
struct CallbackResultPair { |
CallbackResultPair(const CompletionCallback& callback_in, int result_in) |
: callback(callback_in), result(result_in) {} |
@@ -434,9 +483,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
// Queue a frame for sending. |
// |frame| is the frame to send. |
// |priority| is the priority for insertion into the queue. |
- // |stream| is the stream which this IO is associated with (or NULL). |
- void QueueFrame(SpdyFrame* frame, RequestPriority priority, |
- SpdyStream* stream); |
+ void QueueFrame(SpdyFrame* frame, RequestPriority priority); |
// Track active streams in the active stream list. |
void ActivateStream(SpdyStream* stream); |
@@ -462,6 +509,9 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
// Closes all streams. Used as part of shutdown. |
void CloseAllStreams(net::Error status); |
+ void LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, |
+ net::Error status); |
+ |
// Invokes a user callback for stream creation. We provide this method so it |
// can be deferred to the MessageLoop, so we avoid re-entrancy problems. |
void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream); |
@@ -580,8 +630,16 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
// server, but do not have consumers yet. |
PushedStreamMap unclaimed_pushed_streams_; |
- // As we gather data to be sent, we put it into the output queue. |
- OutputQueue queue_; |
+ // Set of all created streams but that have not yet sent any frames. |
+ CreatedStreamSet created_streams_; |
+ |
+ // As streams have data to be sent, we put them into the write queue. |
+ WriteQueue write_queue_; |
+ |
+ // Mapping from SpdyIOBufferProducers to their corresponding SpdyStream |
+ // so that when a stream is destroyed, we can remove the corresponding |
+ // producer from |write_queue_|. |
+ StreamProducerMap stream_producers_; |
// The packet we are currently sending. |
bool write_pending_; // Will be true when a write is in progress. |