15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2009 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/output_ordering.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include <utility> 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/flip_config.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/sm_connection.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OutputOrdering::PriorityMapPointer::PriorityMapPointer() 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : ring(NULL), alarm_enabled(false) {} 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)OutputOrdering::PriorityMapPointer::~PriorityMapPointer() {} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double OutputOrdering::server_think_time_in_s_ = 0.0; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OutputOrdering::OutputOrdering(SMConnectionInterface* connection) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : first_data_senders_threshold_(kInitialDataSendersThreshold), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_(connection) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server_ = connection->epoll_server(); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)OutputOrdering::~OutputOrdering() { Reset(); } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::Reset() { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!stream_ids_.empty()) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamIdToPriorityMap::iterator sitpmi = stream_ids_.begin(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PriorityMapPointer& pmp = sitpmi->second; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pmp.alarm_enabled) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server_->UnregisterAlarm(pmp.alarm_token); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_ids_.erase(sitpmi); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_map_.clear(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_data_senders_.clear(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool OutputOrdering::ExistsInPriorityMaps(uint32 stream_id) const { 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StreamIdToPriorityMap::const_iterator sitpmi = stream_ids_.find(stream_id); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sitpmi != stream_ids_.end(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OutputOrdering::BeginOutputtingAlarm::BeginOutputtingAlarm( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputOrdering* oo, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OutputOrdering::PriorityMapPointer* pmp, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MemCacheIter& mci) 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : output_ordering_(oo), pmp_(pmp), mci_(mci), epoll_server_(NULL) {} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OutputOrdering::BeginOutputtingAlarm::~BeginOutputtingAlarm() { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (epoll_server_ && pmp_->alarm_enabled) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server_->UnregisterAlarm(pmp_->alarm_token); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 OutputOrdering::BeginOutputtingAlarm::OnAlarm() { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnUnregistration(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_ordering_->MoveToActive(pmp_, mci_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "ON ALARM! Should now start to output..."; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::BeginOutputtingAlarm::OnRegistration( 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EpollServer::AlarmRegToken& tok, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EpollServer* eps) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server_ = eps; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pmp_->alarm_token = tok; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pmp_->alarm_enabled = true; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::BeginOutputtingAlarm::OnUnregistration() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pmp_->alarm_enabled = false; 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delete this; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::BeginOutputtingAlarm::OnShutdown(EpollServer* eps) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnUnregistration(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::MoveToActive(PriorityMapPointer* pmp, MemCacheIter mci) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "Moving to active!"; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_data_senders_.push_back(mci); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pmp->ring = &first_data_senders_; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pmp->it = first_data_senders_.end(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --pmp->it; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_->ReadyToSend(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::AddToOutputOrder(const MemCacheIter& mci) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ExistsInPriorityMaps(mci.stream_id)) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "OOps, already was inserted here?!"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double think_time_in_s = server_think_time_in_s_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string x_server_latency = 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mci.file_data->headers()->GetHeader("X-Server-Latency").as_string(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!x_server_latency.empty()) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* endp; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double tmp_think_time_in_s = strtod(x_server_latency.c_str(), &endp); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (endp != x_server_latency.c_str() + x_server_latency.size()) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Unable to understand X-Server-Latency of: " 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << x_server_latency 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << " for resource: " << mci.file_data->filename().c_str(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) think_time_in_s = tmp_think_time_in_s; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamIdToPriorityMap::iterator sitpmi; 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sitpmi = stream_ids_.insert(std::pair<uint32, PriorityMapPointer>( 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mci.stream_id, PriorityMapPointer())).first; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PriorityMapPointer& pmp = sitpmi->second; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BeginOutputtingAlarm* boa = new BeginOutputtingAlarm(this, &pmp, mci); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Server think time: " << think_time_in_s; 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) epoll_server_->RegisterAlarmApproximateDelta(think_time_in_s * 1000000, boa); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::SpliceToPriorityRing(PriorityRing::iterator pri) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter& mci = *pri; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PriorityMap::iterator pmi = priority_map_.find(mci.priority); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pmi == priority_map_.end()) { 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pmi = priority_map_.insert(std::pair<uint32, PriorityRing>( 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mci.priority, PriorityRing())).first; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) pmi->second.splice(pmi->second.end(), first_data_senders_, pri); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamIdToPriorityMap::iterator sitpmi = stream_ids_.find(mci.stream_id); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sitpmi->second.ring = &(pmi->second); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MemCacheIter* OutputOrdering::GetIter() { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!first_data_senders_.empty()) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter& mci = first_data_senders_.front(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mci.bytes_sent >= first_data_senders_threshold_) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpliceToPriorityRing(first_data_senders_.begin()); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_data_senders_.splice(first_data_senders_.end(), 142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) first_data_senders_, 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) first_data_senders_.begin()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci.max_segment_size = kInitialDataSendersThreshold; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &mci; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!priority_map_.empty()) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PriorityRing& first_ring = priority_map_.begin()->second; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_ring.empty()) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_map_.erase(priority_map_.begin()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemCacheIter& mci = first_ring.front(); 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) first_ring.splice(first_ring.end(), first_ring, first_ring.begin()); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mci.max_segment_size = kSpdySegmentSize; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &mci; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OutputOrdering::RemoveStreamId(uint32 stream_id) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamIdToPriorityMap::iterator sitpmi = stream_ids_.find(stream_id); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sitpmi == stream_ids_.end()) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PriorityMapPointer& pmp = sitpmi->second; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pmp.alarm_enabled) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) epoll_server_->UnregisterAlarm(pmp.alarm_token); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pmp.ring->erase(pmp.it); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_ids_.erase(sitpmi); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 176