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