epoll_server_(epoll_server),
helper_(new QuicEpollConnectionHelper(epoll_server_)),
supported_versions_(supported_versions),
- supported_versions_no_flow_control_(supported_versions),
- supported_versions_no_connection_flow_control_(supported_versions),
current_packet_(NULL),
framer_(supported_versions, /*unused*/ QuicTime::Zero(), true),
framer_visitor_(new QuicFramerVisitor(this)) {
DCHECK(writer_ == NULL);
writer_.reset(CreateWriter(fd));
time_wait_list_manager_.reset(CreateQuicTimeWaitListManager());
-
- // Remove all versions > QUIC_VERSION_16 from the
- // supported_versions_no_flow_control_ vector.
- QuicVersionVector::iterator it =
- find(supported_versions_no_flow_control_.begin(),
- supported_versions_no_flow_control_.end(), QUIC_VERSION_17);
- if (it != supported_versions_no_flow_control_.end()) {
- supported_versions_no_flow_control_.erase(
- supported_versions_no_flow_control_.begin(), it + 1);
- }
- CHECK(!supported_versions_no_flow_control_.empty());
-
- // Remove all versions > QUIC_VERSION_18 from the
- // supported_versions_no_connection_flow_control_ vector.
- QuicVersionVector::iterator connection_it = find(
- supported_versions_no_connection_flow_control_.begin(),
- supported_versions_no_connection_flow_control_.end(), QUIC_VERSION_19);
- if (connection_it != supported_versions_no_connection_flow_control_.end()) {
- supported_versions_no_connection_flow_control_.erase(
- supported_versions_no_connection_flow_control_.begin(),
- connection_it + 1);
- }
- CHECK(!supported_versions_no_connection_flow_control_.empty());
}
void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
// We got an EPOLLOUT: the socket should not be blocked.
writer_->SetWritable();
- // Give each writer one attempt to write.
- int num_writers = write_blocked_list_.size();
- for (int i = 0; i < num_writers; ++i) {
- if (write_blocked_list_.empty()) {
- return;
- }
+ // Give all the blocked writers one chance to write, until we're blocked again
+ // or there's no work left.
+ while (!write_blocked_list_.empty() && !writer_->IsWriteBlocked()) {
QuicBlockedWriterInterface* blocked_writer =
write_blocked_list_.begin()->first;
write_blocked_list_.erase(write_blocked_list_.begin());
blocked_writer->OnCanWrite();
- if (writer_->IsWriteBlocked()) {
- // We were unable to write. Wait for the next EPOLLOUT. The writer is
- // responsible for adding itself to the blocked list via OnWriteBlocked().
- return;
- }
}
}
CleanUpSession(it);
}
-void QuicDispatcher::OnWriteBlocked(QuicBlockedWriterInterface* writer) {
- DCHECK(writer_->IsWriteBlocked());
- write_blocked_list_.insert(make_pair(writer, true));
+void QuicDispatcher::OnWriteBlocked(
+ QuicBlockedWriterInterface* blocked_writer) {
+ if (!writer_->IsWriteBlocked()) {
+ LOG(DFATAL) <<
+ "QuicDispatcher::OnWriteBlocked called when the writer is not blocked.";
+ // Return without adding the connection to the blocked list, to avoid
+ // infinite loops in OnCanWrite.
+ return;
+ }
+ write_blocked_list_.insert(make_pair(blocked_writer, true));
}
QuicPacketWriter* QuicDispatcher::CreateWriter(int fd) {
QuicConnectionId connection_id,
const IPEndPoint& server_address,
const IPEndPoint& client_address) {
- if (FLAGS_enable_quic_stream_flow_control_2 &&
- FLAGS_enable_quic_connection_flow_control_2) {
- DLOG(INFO) << "Creating QuicDispatcher with all versions.";
- return new QuicConnection(connection_id, client_address, helper_.get(),
- writer_.get(), true, supported_versions_);
- }
-
- if (FLAGS_enable_quic_stream_flow_control_2 &&
- !FLAGS_enable_quic_connection_flow_control_2) {
- DLOG(INFO) << "Connection flow control disabled, creating QuicDispatcher "
- << "WITHOUT version 19 or higher.";
- return new QuicConnection(connection_id, client_address, helper_.get(),
- writer_.get(), true,
- supported_versions_no_connection_flow_control_);
- }
-
- DLOG(INFO) << "Flow control disabled, creating QuicDispatcher WITHOUT "
- << "version 17 or higher.";
- return new QuicConnection(connection_id, client_address, helper_.get(),
- writer_.get(), true,
- supported_versions_no_flow_control_);
+ return new QuicConnection(connection_id,
+ client_address,
+ helper_.get(),
+ writer_.get(),
+ false /* owns_writer */,
+ true /* is_server */,
+ supported_versions_);
}
QuicTimeWaitListManager* QuicDispatcher::CreateQuicTimeWaitListManager() {