1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/output_ordering.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/flip_config.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/sm_connection.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace net { 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsendouble OutputOrdering::server_think_time_in_s_ = 0.0; 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 16dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenOutputOrdering::OutputOrdering(SMConnectionInterface* connection) 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : first_data_senders_threshold_(kInitialDataSendersThreshold), 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_(connection) { 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (connection) 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_ = connection->epoll_server(); 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 23dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenOutputOrdering::~OutputOrdering() {} 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::Reset() { 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (!stream_ids_.empty()) { 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StreamIdToPriorityMap::iterator sitpmi = stream_ids_.begin(); 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PriorityMapPointer& pmp = sitpmi->second; 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (pmp.alarm_enabled) { 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_->UnregisterAlarm(pmp.alarm_token); 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen stream_ids_.erase(sitpmi); 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen priority_map_.clear(); 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_data_senders_.clear(); 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool OutputOrdering::ExistsInPriorityMaps(uint32 stream_id) { 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StreamIdToPriorityMap::iterator sitpmi = stream_ids_.find(stream_id); 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return sitpmi != stream_ids_.end(); 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 43dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenOutputOrdering::BeginOutputtingAlarm::BeginOutputtingAlarm( 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OutputOrdering* oo, 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OutputOrdering::PriorityMapPointer* pmp, 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const MemCacheIter& mci) 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : output_ordering_(oo), 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp_(pmp), 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci_(mci), 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_(NULL) { 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 53dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenOutputOrdering::BeginOutputtingAlarm::~BeginOutputtingAlarm() { 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (epoll_server_ && pmp_->alarm_enabled) 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_->UnregisterAlarm(pmp_->alarm_token); 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenint64 OutputOrdering::BeginOutputtingAlarm::OnAlarm() { 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OnUnregistration(); 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen output_ordering_->MoveToActive(pmp_, mci_); 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << "ON ALARM! Should now start to output..."; 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete this; 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return 0; 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::BeginOutputtingAlarm::OnRegistration( 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const EpollServer::AlarmRegToken& tok, 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EpollServer* eps) { 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_ = eps; 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp_->alarm_token = tok; 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp_->alarm_enabled = true; 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::BeginOutputtingAlarm::OnUnregistration() { 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp_->alarm_enabled = false; 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::BeginOutputtingAlarm::OnShutdown(EpollServer* eps) { 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen OnUnregistration(); 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::MoveToActive(PriorityMapPointer* pmp, MemCacheIter mci) { 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(2) << "Moving to active!"; 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_data_senders_.push_back(mci); 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp->ring = &first_data_senders_; 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp->it = first_data_senders_.end(); 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen --pmp->it; 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen connection_->ReadyToSend(); 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::AddToOutputOrder(const MemCacheIter& mci) { 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ExistsInPriorityMaps(mci.stream_id)) 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(ERROR) << "OOps, already was inserted here?!"; 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double think_time_in_s = server_think_time_in_s_; 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string x_server_latency = 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci.file_data->headers->GetHeader("X-Server-Latency").as_string(); 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!x_server_latency.empty()) { 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char* endp; 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double tmp_think_time_in_s = strtod(x_server_latency.c_str(), &endp); 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (endp != x_server_latency.c_str() + x_server_latency.size()) { 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(ERROR) << "Unable to understand X-Server-Latency of: " 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << x_server_latency << " for resource: " 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << mci.file_data->filename.c_str(); 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen think_time_in_s = tmp_think_time_in_s; 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StreamIdToPriorityMap::iterator sitpmi; 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sitpmi = stream_ids_.insert( 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::pair<uint32, PriorityMapPointer>(mci.stream_id, 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PriorityMapPointer())).first; 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PriorityMapPointer& pmp = sitpmi->second; 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen BeginOutputtingAlarm* boa = new BeginOutputtingAlarm(this, &pmp, mci); 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "Server think time: " << think_time_in_s; 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_->RegisterAlarmApproximateDelta( 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen think_time_in_s * 1000000, boa); 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::SpliceToPriorityRing(PriorityRing::iterator pri) { 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MemCacheIter& mci = *pri; 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PriorityMap::iterator pmi = priority_map_.find(mci.priority); 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (pmi == priority_map_.end()) { 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmi = priority_map_.insert( 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::pair<uint32, PriorityRing>(mci.priority, PriorityRing())).first; 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmi->second.splice(pmi->second.end(), 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_data_senders_, 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pri); 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StreamIdToPriorityMap::iterator sitpmi = stream_ids_.find(mci.stream_id); 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sitpmi->second.ring = &(pmi->second); 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 136dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenMemCacheIter* OutputOrdering::GetIter() { 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (!first_data_senders_.empty()) { 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MemCacheIter& mci = first_data_senders_.front(); 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (mci.bytes_sent >= first_data_senders_threshold_) { 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SpliceToPriorityRing(first_data_senders_.begin()); 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_data_senders_.splice(first_data_senders_.end(), 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_data_senders_, 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_data_senders_.begin()); 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci.max_segment_size = kInitialDataSendersThreshold; 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return &mci; 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (!priority_map_.empty()) { 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PriorityRing& first_ring = priority_map_.begin()->second; 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (first_ring.empty()) { 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen priority_map_.erase(priority_map_.begin()); 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MemCacheIter& mci = first_ring.front(); 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_ring.splice(first_ring.end(), 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_ring, 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_ring.begin()); 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen mci.max_segment_size = kSpdySegmentSize; 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return &mci; 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return NULL; 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OutputOrdering::RemoveStreamId(uint32 stream_id) { 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StreamIdToPriorityMap::iterator sitpmi = stream_ids_.find(stream_id); 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (sitpmi == stream_ids_.end()) 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PriorityMapPointer& pmp = sitpmi->second; 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (pmp.alarm_enabled) 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen epoll_server_->UnregisterAlarm(pmp.alarm_token); 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen else 174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pmp.ring->erase(pmp.it); 175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen stream_ids_.erase(sitpmi); 176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace net 179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 180