| Index: chrome/browser/net/passive_log_collector.cc
|
| ===================================================================
|
| --- chrome/browser/net/passive_log_collector.cc (revision 48758)
|
| +++ chrome/browser/net/passive_log_collector.cc (working copy)
|
| @@ -6,6 +6,7 @@
|
|
|
| #include <algorithm>
|
|
|
| +#include "base/compiler_specific.h"
|
| #include "base/string_util.h"
|
| #include "base/format_macros.h"
|
| #include "chrome/browser/chrome_thread.h"
|
| @@ -13,16 +14,10 @@
|
|
|
| namespace {
|
|
|
| -const size_t kMaxNumEntriesPerLog = 50;
|
| -const size_t kMaxConnectJobGraveyardSize = 3;
|
| -const size_t kMaxRequestGraveyardSize = 25;
|
| -const size_t kMaxLiveRequests = 200;
|
| +// TODO(eroman): Do something with the truncation count.
|
|
|
| -// Sort function on source ID.
|
| -bool OrderBySourceID(const PassiveLogCollector::RequestInfo& a,
|
| - const PassiveLogCollector::RequestInfo& b) {
|
| - return a.source_id < b.source_id;
|
| -}
|
| +const size_t kMaxNumEntriesPerLog = 30;
|
| +const size_t kMaxRequestsPerTracker = 200;
|
|
|
| void AddEntryToRequestInfo(const PassiveLogCollector::Entry& entry,
|
| PassiveLogCollector::RequestInfo* out_info) {
|
| @@ -35,45 +30,12 @@
|
| }
|
| }
|
|
|
| -void AppendToRequestInfo(const PassiveLogCollector::RequestInfo& info,
|
| - PassiveLogCollector::RequestInfo* out_info) {
|
| - for (size_t i = 0; i < info.entries.size(); ++i)
|
| - AddEntryToRequestInfo(info.entries[i], out_info);
|
| -}
|
| -
|
| -// Appends all of the logged events in |input| to |out|.
|
| -void AppendAllEntriesFromRequests(
|
| - const PassiveLogCollector::RequestInfoList& input,
|
| - PassiveLogCollector::EntryList* out) {
|
| - for (size_t i = 0; i < input.size(); ++i) {
|
| - const PassiveLogCollector::EntryList& entries = input[i].entries;
|
| - out->insert(out->end(), entries.begin(), entries.end());
|
| - }
|
| -}
|
| -
|
| // Comparator to sort entries by their |order| property, ascending.
|
| bool SortByOrderComparator(const PassiveLogCollector::Entry& a,
|
| const PassiveLogCollector::Entry& b) {
|
| return a.order < b.order;
|
| }
|
|
|
| -void SetSubordinateSource(PassiveLogCollector::RequestInfo* info,
|
| - const PassiveLogCollector::Entry& entry) {
|
| - info->subordinate_source.id = static_cast<net::NetLogIntegerParameter*>(
|
| - entry.params.get())->value();
|
| - switch (entry.type) {
|
| - case net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID:
|
| - info->subordinate_source.type = net::NetLog::SOURCE_CONNECT_JOB;
|
| - break;
|
| - case net::NetLog::TYPE_SOCKET_POOL_SOCKET_ID:
|
| - info->subordinate_source.type = net::NetLog::SOURCE_SOCKET;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| } // namespace
|
|
|
| //----------------------------------------------------------------------------
|
| @@ -81,9 +43,24 @@
|
| //----------------------------------------------------------------------------
|
|
|
| PassiveLogCollector::PassiveLogCollector()
|
| - : url_request_tracker_(&connect_job_tracker_, &socket_tracker_),
|
| - socket_stream_tracker_(&connect_job_tracker_, &socket_tracker_),
|
| + : ALLOW_THIS_IN_INITIALIZER_LIST(connect_job_tracker_(this)),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(url_request_tracker_(this)),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(socket_stream_tracker_(this)),
|
| num_events_seen_(0) {
|
| +
|
| + // Define the mapping between source types and the tracker objects.
|
| + memset(&trackers_[0], 0, sizeof(trackers_));
|
| + trackers_[net::NetLog::SOURCE_URL_REQUEST] = &url_request_tracker_;
|
| + trackers_[net::NetLog::SOURCE_SOCKET_STREAM] = &socket_stream_tracker_;
|
| + trackers_[net::NetLog::SOURCE_CONNECT_JOB] = &connect_job_tracker_;
|
| + trackers_[net::NetLog::SOURCE_SOCKET] = &socket_tracker_;
|
| + trackers_[net::NetLog::SOURCE_INIT_PROXY_RESOLVER] =
|
| + &init_proxy_resolver_tracker_;
|
| + trackers_[net::NetLog::SOURCE_SPDY_SESSION] = &spdy_session_tracker_;
|
| +
|
| + // Make sure our mapping is up-to-date.
|
| + for (size_t i = 0; i < arraysize(trackers_); ++i)
|
| + DCHECK(trackers_[i]) << "Unhandled SourceType: " << i;
|
| }
|
|
|
| PassiveLogCollector::~PassiveLogCollector() {
|
| @@ -98,32 +75,22 @@
|
| // Package the parameters into a single struct for convenience.
|
| Entry entry(num_events_seen_++, type, time, source, phase, params);
|
|
|
| - switch (entry.source.type) {
|
| - case net::NetLog::SOURCE_URL_REQUEST:
|
| - url_request_tracker_.OnAddEntry(entry);
|
| - break;
|
| - case net::NetLog::SOURCE_SOCKET_STREAM:
|
| - socket_stream_tracker_.OnAddEntry(entry);
|
| - break;
|
| - case net::NetLog::SOURCE_CONNECT_JOB:
|
| - connect_job_tracker_.OnAddEntry(entry);
|
| - break;
|
| - case net::NetLog::SOURCE_SOCKET:
|
| - socket_tracker_.OnAddEntry(entry);
|
| - break;
|
| - case net::NetLog::SOURCE_INIT_PROXY_RESOLVER:
|
| - init_proxy_resolver_tracker_.OnAddEntry(entry);
|
| - break;
|
| - default:
|
| - // Drop all other logged events.
|
| - break;
|
| - }
|
| + RequestTrackerBase* tracker = GetTrackerForSourceType(entry.source.type);
|
| + if (tracker)
|
| + tracker->OnAddEntry(entry);
|
| }
|
|
|
| +PassiveLogCollector::RequestTrackerBase*
|
| +PassiveLogCollector::GetTrackerForSourceType(
|
| + net::NetLog::SourceType source_type) {
|
| + DCHECK_LE(source_type, static_cast<int>(arraysize(trackers_)));
|
| + DCHECK_GE(source_type, 0);
|
| + return trackers_[source_type];
|
| +}
|
| +
|
| void PassiveLogCollector::Clear() {
|
| - connect_job_tracker_.Clear();
|
| - url_request_tracker_.Clear();
|
| - socket_stream_tracker_.Clear();
|
| + for (size_t i = 0; i < arraysize(trackers_); ++i)
|
| + trackers_[i]->Clear();
|
| }
|
|
|
| void PassiveLogCollector::GetAllCapturedEvents(EntryList* out) const {
|
| @@ -131,14 +98,9 @@
|
|
|
| // Append all of the captured entries held by the various trackers to
|
| // |out|.
|
| - socket_stream_tracker_.AppendAllEntries(out);
|
| - url_request_tracker_.AppendAllEntries(out);
|
| - spdy_session_tracker_.AppendAllEntries(out);
|
| + for (size_t i = 0; i < arraysize(trackers_); ++i)
|
| + trackers_[i]->AppendAllEntries(out);
|
|
|
| - const EntryList& proxy_entries =
|
| - init_proxy_resolver_tracker_.entries();
|
| - out->insert(out->end(), proxy_entries.begin(), proxy_entries.end());
|
| -
|
| // Now sort the list of entries by their insertion time (ascending).
|
| std::sort(out->begin(), out->end(), &SortByOrderComparator);
|
| }
|
| @@ -169,124 +131,166 @@
|
| //----------------------------------------------------------------------------
|
|
|
| PassiveLogCollector::RequestTrackerBase::RequestTrackerBase(
|
| - size_t max_graveyard_size)
|
| - : max_graveyard_size_(max_graveyard_size),
|
| - next_graveyard_index_(0) {
|
| + size_t max_graveyard_size, PassiveLogCollector* parent)
|
| + : max_graveyard_size_(max_graveyard_size), parent_(parent) {
|
| }
|
|
|
| +PassiveLogCollector::RequestTrackerBase::~RequestTrackerBase() {}
|
| +
|
| void PassiveLogCollector::RequestTrackerBase::OnAddEntry(const Entry& entry) {
|
| - RequestInfo& info = live_requests_[entry.source.id];
|
| + RequestInfo& info = requests_[entry.source.id];
|
| info.source_id = entry.source.id; // In case this is a new entry.
|
| Action result = DoAddEntry(entry, &info);
|
|
|
| - switch (result) {
|
| - case ACTION_MOVE_TO_GRAVEYARD:
|
| - InsertIntoGraveyard(info);
|
| - // (fall-through)
|
| - case ACTION_DELETE:
|
| - RemoveFromLiveRequests(entry.source.id);
|
| - break;
|
| - default:
|
| - break;
|
| + if (result != ACTION_NONE) {
|
| + // We are either queuing it for deletion, or deleting it immediately.
|
| + // If someone else holds a reference to this source, defer the deletion
|
| + // until all the references are released.
|
| + info.is_alive = false;
|
| + if (info.reference_count == 0) {
|
| + switch (result) {
|
| + case ACTION_MOVE_TO_GRAVEYARD:
|
| + AddToDeletionQueue(info.source_id);
|
| + break;
|
| + case ACTION_DELETE:
|
| + DeleteRequestInfo(info.source_id);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
| - if (live_requests_.size() > kMaxLiveRequests) {
|
| + if (requests_.size() > kMaxRequestsPerTracker) {
|
| // This is a safety net in case something went wrong, to avoid continually
|
| // growing memory.
|
| LOG(WARNING) << "The passive log data has grown larger "
|
| "than expected, resetting";
|
| - live_requests_.clear();
|
| + Clear();
|
| }
|
| }
|
|
|
| -PassiveLogCollector::RequestInfoList
|
| -PassiveLogCollector::RequestTrackerBase::GetLiveRequests() const {
|
| - RequestInfoList list;
|
| +void PassiveLogCollector::RequestTrackerBase::DeleteRequestInfo(
|
| + uint32 source_id) {
|
| + SourceIDToInfoMap::iterator it = requests_.find(source_id);
|
| + DCHECK(it != requests_.end());
|
| + // The request should not be in the deletion queue.
|
| + DCHECK(std::find(deletion_queue_.begin(), deletion_queue_.end(),
|
| + source_id) == deletion_queue_.end());
|
| + ReleaseAllReferencesToDependencies(&(it->second));
|
| + requests_.erase(it);
|
| +}
|
|
|
| - // Copy all of the live requests into the vector.
|
| - for (SourceIDToInfoMap::const_iterator it = live_requests_.begin();
|
| - it != live_requests_.end();
|
| +void PassiveLogCollector::RequestTrackerBase::Clear() {
|
| + deletion_queue_.clear();
|
| +
|
| + // Release all references held to dependent sources.
|
| + for (SourceIDToInfoMap::iterator it = requests_.begin();
|
| + it != requests_.end();
|
| ++it) {
|
| - list.push_back(it->second);
|
| - // We pass the copy (made by the list insert), so changes made in
|
| - // OnLiveRequest are only seen by our caller.
|
| - OnLiveRequest(&list.back());
|
| - std::sort(list.back().entries.begin(), list.back().entries.end(),
|
| - SortByOrderComparator);
|
| + ReleaseAllReferencesToDependencies(&(it->second));
|
| }
|
| -
|
| - std::sort(list.begin(), list.end(), OrderBySourceID);
|
| - return list;
|
| + requests_.clear();
|
| }
|
|
|
| -void PassiveLogCollector::RequestTrackerBase::ClearRecentlyDeceased() {
|
| - next_graveyard_index_ = 0;
|
| - graveyard_.clear();
|
| +void PassiveLogCollector::RequestTrackerBase::AppendAllEntries(
|
| + EntryList* out) const {
|
| + // Append all of the entries for each of the sources.
|
| + for (SourceIDToInfoMap::const_iterator it = requests_.begin();
|
| + it != requests_.end();
|
| + ++it) {
|
| + const RequestInfo& info = it->second;
|
| + out->insert(out->end(), info.entries.begin(), info.entries.end());
|
| + }
|
| }
|
|
|
| -// Returns a list of recently completed Requests.
|
| -PassiveLogCollector::RequestInfoList
|
| -PassiveLogCollector::RequestTrackerBase::GetRecentlyDeceased() const {
|
| - RequestInfoList list;
|
| +void PassiveLogCollector::RequestTrackerBase::AddToDeletionQueue(
|
| + uint32 source_id) {
|
| + DCHECK(requests_.find(source_id) != requests_.end());
|
| + DCHECK(!requests_.find(source_id)->second.is_alive);
|
| + DCHECK_GE(requests_.find(source_id)->second.reference_count, 0);
|
| + DCHECK_LE(deletion_queue_.size(), max_graveyard_size_);
|
|
|
| - // Copy the items from |graveyard_| (our circular queue of recently
|
| - // deceased request infos) into a vector, ordered from oldest to newest.
|
| - for (size_t i = 0; i < graveyard_.size(); ++i) {
|
| - size_t index = (next_graveyard_index_ + i) % graveyard_.size();
|
| - list.push_back(graveyard_[index]);
|
| + deletion_queue_.push_back(source_id);
|
| +
|
| + // After the deletion queue has reached its maximum size, start
|
| + // deleting requests in FIFO order.
|
| + if (deletion_queue_.size() > max_graveyard_size_) {
|
| + uint32 oldest = deletion_queue_.front();
|
| + deletion_queue_.pop_front();
|
| + DeleteRequestInfo(oldest);
|
| }
|
| - return list;
|
| }
|
|
|
| -PassiveLogCollector::RequestInfo*
|
| -PassiveLogCollector::RequestTrackerBase::GetRequestInfo(uint32 source_id) {
|
| - // Look for it in the live requests first.
|
| - SourceIDToInfoMap::iterator it = live_requests_.find(source_id);
|
| - if (it != live_requests_.end())
|
| - return &(it->second);
|
| +void PassiveLogCollector::RequestTrackerBase::AdjustReferenceCountForSource(
|
| + int offset, uint32 source_id) {
|
| + DCHECK(offset == -1 || offset == 1) << "invalid offset: " << offset;
|
|
|
| - // Otherwise, scan through the graveyard to find an entry for |source_id|.
|
| - for (size_t i = 0; i < graveyard_.size(); ++i) {
|
| - if (graveyard_[i].source_id == source_id) {
|
| - return &graveyard_[i];
|
| + // In general it is invalid to call AdjustReferenceCountForSource() on
|
| + // source that doesn't exist. However, it is possible that if
|
| + // RequestTrackerBase::Clear() was previously called this can happen.
|
| + // TODO(eroman): Add a unit-test that exercises this case.
|
| + SourceIDToInfoMap::iterator it = requests_.find(source_id);
|
| + if (it == requests_.end())
|
| + return;
|
| +
|
| + RequestInfo& info = it->second;
|
| + DCHECK_GE(info.reference_count, 0);
|
| + DCHECK_GE(info.reference_count + offset, 0);
|
| + info.reference_count += offset;
|
| +
|
| + if (!info.is_alive) {
|
| + if (info.reference_count == 1 && offset == 1) {
|
| + // If we just added a reference to a dead source that had no references,
|
| + // it must have been in the deletion queue, so remove it from the queue.
|
| + DeletionQueue::iterator it =
|
| + std::remove(deletion_queue_.begin(), deletion_queue_.end(),
|
| + source_id);
|
| + DCHECK(it != deletion_queue_.end());
|
| + deletion_queue_.erase(it);
|
| + } else if (info.reference_count == 0) {
|
| + // If we just released the final reference to a dead request, go ahead
|
| + // and delete it right away.
|
| + DeleteRequestInfo(source_id);
|
| }
|
| }
|
| - return NULL;
|
| }
|
|
|
| -void PassiveLogCollector::RequestTrackerBase::RemoveFromLiveRequests(
|
| - uint32 source_id) {
|
| - // Remove from |live_requests_|.
|
| - SourceIDToInfoMap::iterator it = live_requests_.find(source_id);
|
| - // TODO(eroman): Shouldn't have this 'if', is it actually really necessary?
|
| - if (it != live_requests_.end())
|
| - live_requests_.erase(it);
|
| -}
|
| +void PassiveLogCollector::RequestTrackerBase::AddReferenceToSourceDependency(
|
| + const net::NetLog::Source& source, RequestInfo* info) {
|
| + // Find the tracker which should be holding |source|.
|
| + DCHECK(parent_);
|
| + RequestTrackerBase* tracker =
|
| + parent_->GetTrackerForSourceType(source.type);
|
| + DCHECK(tracker);
|
|
|
| -void PassiveLogCollector::RequestTrackerBase::Clear() {
|
| - ClearRecentlyDeceased();
|
| - live_requests_.clear();
|
| -}
|
| + // Tell the owning tracker to increment the reference count of |source|.
|
| + tracker->AdjustReferenceCountForSource(1, source.id);
|
|
|
| -void PassiveLogCollector::RequestTrackerBase::AppendAllEntries(
|
| - EntryList* out) const {
|
| - AppendAllEntriesFromRequests(GetLiveRequests(), out);
|
| - AppendAllEntriesFromRequests(GetRecentlyDeceased(), out);
|
| + // Make a note to release this reference once |info| is destroyed.
|
| + info->dependencies.push_back(source);
|
| }
|
|
|
| -void PassiveLogCollector::RequestTrackerBase::InsertIntoGraveyard(
|
| - const RequestInfo& info) {
|
| - // Enforce a bound on the graveyard size, by treating it as a
|
| - // circular buffer.
|
| - if (graveyard_.size() < max_graveyard_size_) {
|
| - // Still growing to maximum capacity.
|
| - DCHECK_EQ(next_graveyard_index_, graveyard_.size());
|
| - graveyard_.push_back(info);
|
| - } else {
|
| - // At maximum capacity, overwite the oldest entry.
|
| - graveyard_[next_graveyard_index_] = info;
|
| +void
|
| +PassiveLogCollector::RequestTrackerBase::ReleaseAllReferencesToDependencies(
|
| + RequestInfo* info) {
|
| + // Release all references |info| was holding to dependent sources.
|
| + for (SourceDependencyList::const_iterator it = info->dependencies.begin();
|
| + it != info->dependencies.end(); ++it) {
|
| + const net::NetLog::Source& source = *it;
|
| +
|
| + // Find the tracker which should be holding |source|.
|
| + DCHECK(parent_);
|
| + RequestTrackerBase* tracker =
|
| + parent_->GetTrackerForSourceType(source.type);
|
| + DCHECK(tracker);
|
| +
|
| + // Tell the owning tracker to decrement the reference count of |source|.
|
| + tracker->AdjustReferenceCountForSource(-1, source.id);
|
| }
|
| - next_graveyard_index_ = (next_graveyard_index_ + 1) % max_graveyard_size_;
|
| +
|
| + info->dependencies.clear();
|
| }
|
|
|
| //----------------------------------------------------------------------------
|
| @@ -295,8 +299,9 @@
|
|
|
| const size_t PassiveLogCollector::ConnectJobTracker::kMaxGraveyardSize = 15;
|
|
|
| -PassiveLogCollector::ConnectJobTracker::ConnectJobTracker()
|
| - : RequestTrackerBase(kMaxGraveyardSize) {
|
| +PassiveLogCollector::ConnectJobTracker::ConnectJobTracker(
|
| + PassiveLogCollector* parent)
|
| + : RequestTrackerBase(kMaxGraveyardSize, parent) {
|
| }
|
|
|
| PassiveLogCollector::RequestTrackerBase::Action
|
| @@ -304,8 +309,10 @@
|
| RequestInfo* out_info) {
|
| AddEntryToRequestInfo(entry, out_info);
|
|
|
| - if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) {
|
| - SetSubordinateSource(out_info, entry);
|
| + if (entry.type == net::NetLog::TYPE_CONNECT_JOB_SET_SOCKET) {
|
| + const net::NetLog::Source& source_dependency =
|
| + static_cast<net::NetLogSourceParameter*>(entry.params.get())->value();
|
| + AddReferenceToSourceDependency(source_dependency, out_info);
|
| }
|
|
|
| // If this is the end of the connect job, move the request to the graveyard.
|
| @@ -317,29 +324,6 @@
|
| return ACTION_NONE;
|
| }
|
|
|
| -void PassiveLogCollector::ConnectJobTracker::AppendLogEntries(
|
| - RequestInfo* out_info, uint32 connect_id) {
|
| - RequestInfo* connect_info = GetRequestInfo(connect_id);
|
| - if (!connect_info) {
|
| - net::NetLogStringParameter* text = new net::NetLogStringParameter(
|
| - "todo", StringPrintf("Used ConnectJob id=%u", connect_id));
|
| - Entry new_entry(0, net::NetLog::TYPE_TODO_STRING, base::TimeTicks(),
|
| - net::NetLog::Source(net::NetLog::SOURCE_CONNECT_JOB,
|
| - connect_id),
|
| - net::NetLog::PHASE_NONE, text);
|
| - AddEntryToRequestInfo(new_entry, out_info);
|
| - return;
|
| - }
|
| -
|
| - AppendToRequestInfo(*connect_info, out_info);
|
| - std::sort(out_info->entries.begin(), out_info->entries.end(),
|
| - &SortByOrderComparator);
|
| - out_info->num_entries_truncated += connect_info->num_entries_truncated;
|
| -
|
| - if (connect_info->subordinate_source.is_valid())
|
| - AppendLogEntries(out_info, connect_info->subordinate_source.id);
|
| -}
|
| -
|
| //----------------------------------------------------------------------------
|
| // SocketTracker
|
| //----------------------------------------------------------------------------
|
| @@ -347,148 +331,48 @@
|
| const size_t PassiveLogCollector::SocketTracker::kMaxGraveyardSize = 15;
|
|
|
| PassiveLogCollector::SocketTracker::SocketTracker()
|
| - : RequestTrackerBase(kMaxGraveyardSize) {
|
| + : RequestTrackerBase(kMaxGraveyardSize, NULL) {
|
| }
|
|
|
| PassiveLogCollector::RequestTrackerBase::Action
|
| PassiveLogCollector::SocketTracker::DoAddEntry(const Entry& entry,
|
| RequestInfo* out_info) {
|
| - int int_arg;
|
| - switch (entry.type) {
|
| - case net::NetLog::TYPE_SOCKET_BYTES_SENT:
|
| - int_arg = static_cast<net::NetLogIntegerParameter*>(
|
| - entry.params.get())->value();
|
| - out_info->total_bytes_transmitted += int_arg;
|
| - out_info->bytes_transmitted += int_arg;
|
| - out_info->last_tx_rx_time = entry.time;
|
| - out_info->last_tx_rx_position = entry.order;
|
| - break;
|
| - case net::NetLog::TYPE_SOCKET_BYTES_RECEIVED:
|
| - int_arg = static_cast<net::NetLogIntegerParameter*>(
|
| - entry.params.get())->value();
|
| - out_info->total_bytes_received += int_arg;
|
| - out_info->bytes_received += int_arg;
|
| - out_info->last_tx_rx_time = entry.time;
|
| - out_info->last_tx_rx_position = entry.order;
|
| - break;
|
| - case net::NetLog::TYPE_TCP_SOCKET_DONE:
|
| - return ACTION_MOVE_TO_GRAVEYARD;
|
| - default:
|
| - AddEntryToRequestInfo(entry, out_info);
|
| - break;
|
| + // TODO(eroman): aggregate the byte counts once truncation starts to happen,
|
| + // to summarize transaction read/writes for each SOCKET_IN_USE
|
| + // section.
|
| + if (entry.type == net::NetLog::TYPE_SOCKET_BYTES_SENT ||
|
| + entry.type == net::NetLog::TYPE_SOCKET_BYTES_RECEIVED) {
|
| + return ACTION_NONE;
|
| }
|
| - return ACTION_NONE;
|
| -}
|
|
|
| -void PassiveLogCollector::SocketTracker::AppendLogEntries(
|
| - RequestInfo* out_info, uint32 socket_id, bool clear) {
|
| - RequestInfo* socket_info = GetRequestInfo(socket_id);
|
| - if (!socket_info) {
|
| - net::NetLogStringParameter* text = new net::NetLogStringParameter(
|
| - "todo", StringPrintf("Used Socket id=%u.", socket_id));
|
| - Entry new_entry(0, net::NetLog::TYPE_TODO_STRING, base::TimeTicks(),
|
| - net::NetLog::Source(net::NetLog::SOURCE_SOCKET, socket_id),
|
| - net::NetLog::PHASE_NONE, text);
|
| - AddEntryToRequestInfo(new_entry, out_info);
|
| - return;
|
| - }
|
| + AddEntryToRequestInfo(entry, out_info);
|
|
|
| - AppendToRequestInfo(*socket_info, out_info);
|
| - out_info->num_entries_truncated += socket_info->num_entries_truncated;
|
| -
|
| - // Synthesize a log entry for bytes sent and received.
|
| - if (socket_info->bytes_transmitted > 0 || socket_info->bytes_received > 0) {
|
| - net::NetLogStringParameter* text = new net::NetLogStringParameter(
|
| - "stats",
|
| - StringPrintf("Tx/Rx: %"PRIu64"/%"PRIu64" [%"PRIu64"/%"PRIu64
|
| - " total on socket] (Bytes)",
|
| - socket_info->bytes_transmitted,
|
| - socket_info->bytes_received,
|
| - socket_info->total_bytes_transmitted,
|
| - socket_info->total_bytes_received));
|
| - Entry new_entry(socket_info->last_tx_rx_position,
|
| - net::NetLog::TYPE_TODO_STRING,
|
| - socket_info->last_tx_rx_time,
|
| - net::NetLog::Source(net::NetLog::SOURCE_SOCKET, socket_id),
|
| - net::NetLog::PHASE_NONE,
|
| - text);
|
| - AddEntryToRequestInfo(new_entry, out_info);
|
| + if (entry.type == net::NetLog::TYPE_SOCKET_ALIVE &&
|
| + entry.phase == net::NetLog::PHASE_END) {
|
| + return ACTION_MOVE_TO_GRAVEYARD;
|
| }
|
| - std::sort(out_info->entries.begin(), out_info->entries.end(),
|
| - &SortByOrderComparator);
|
|
|
| - if (clear)
|
| - ClearInfo(socket_info);
|
| + return ACTION_NONE;
|
| }
|
|
|
| -void PassiveLogCollector::SocketTracker::ClearInfo(RequestInfo* info) {
|
| - info->entries.clear();
|
| - info->num_entries_truncated = 0;
|
| - info->bytes_transmitted = 0;
|
| - info->bytes_received = 0;
|
| - info->last_tx_rx_position = 0;
|
| - info->last_tx_rx_time = base::TimeTicks();
|
| -}
|
| -
|
| //----------------------------------------------------------------------------
|
| // RequestTracker
|
| //----------------------------------------------------------------------------
|
|
|
| const size_t PassiveLogCollector::RequestTracker::kMaxGraveyardSize = 25;
|
|
|
| -PassiveLogCollector::RequestTracker::RequestTracker(
|
| - ConnectJobTracker* connect_job_tracker, SocketTracker* socket_tracker)
|
| - : RequestTrackerBase(kMaxGraveyardSize),
|
| - connect_job_tracker_(connect_job_tracker),
|
| - socket_tracker_(socket_tracker) {
|
| +PassiveLogCollector::RequestTracker::RequestTracker(PassiveLogCollector* parent)
|
| + : RequestTrackerBase(kMaxGraveyardSize, parent) {
|
| }
|
|
|
| PassiveLogCollector::RequestTrackerBase::Action
|
| PassiveLogCollector::RequestTracker::DoAddEntry(const Entry& entry,
|
| RequestInfo* out_info) {
|
| - // We expect up to three events with IDs.
|
| - // - Begin SOCKET_POOL_CONNECT_JOB_ID: Means a ConnectJob was created for
|
| - // this request. Including it for now, but the resulting socket may be
|
| - // used for a different request.
|
| - // - End SOCKET_POOL_CONNECT_JOB_ID: The named ConnectJob completed and
|
| - // this request will be getting the socket from that request.
|
| - // - SOCKET_POOL_SOCKET_ID: The given socket will be used for this request.
|
| - //
|
| - // The action to take when seeing these events depends on the current
|
| - // content of the |subordinate_source| field:
|
| - // |subordinate_source| is invalid (fresh state).
|
| - // - Begin SOCKET_POOL_CONNECT_JOB_ID: Set |subordinate_source|.
|
| - // - End SOCKET_POOL_CONNECT_JOB_ID: Integrate the named ConnectJob ID.
|
| - // - SOCKET_POOL_SOCKET_ID: Set |subordinate_source|.
|
| - // |subordinate_source| is a ConnectJob:
|
| - // - Begin SOCKET_POOL_CONNECT_JOB_ID: Set |subordinate_source|.
|
| - // - End SOCKET_POOL_CONNECT_JOB_ID: Integrate the named ConnectJob ID and
|
| - // clear the |subordinate_source|.
|
| - // - SOCKET_POOL_SOCKET_ID: Set |subordinate_source|. (The request was
|
| - // assigned a new idle socket, after starting a ConnectJob.)
|
| - // |subordinate_source| is a Socket:
|
| - // First, integrate the subordinate socket source, then:
|
| - // - Begin SOCKET_POOL_CONNECT_JOB_ID: Set |subordinate_source|.
|
| - // (Connection restarted with a new ConnectJob.)
|
| - // - End SOCKET_POOL_CONNECT_JOB_ID: Integrate the named ConnectJob ID and
|
| - // clear the |subordinate_source|. (Connection restarted with a late bound
|
| - // ConnectJob.)
|
| - // - SOCKET_POOL_SOCKET_ID: Set |subordinate_source|. (Connection
|
| - // restarted and got an idle socket.)
|
| - if (entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID ||
|
| - entry.type == net::NetLog::TYPE_SOCKET_POOL_SOCKET_ID) {
|
| -
|
| - if (out_info->subordinate_source.is_valid() &&
|
| - out_info->subordinate_source.type == net::NetLog::SOURCE_SOCKET)
|
| - IntegrateSubordinateSource(out_info, true);
|
| -
|
| - SetSubordinateSource(out_info, entry);
|
| -
|
| - if (entry.phase == net::NetLog::PHASE_END &&
|
| - entry.type == net::NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID) {
|
| - IntegrateSubordinateSource(out_info, true);
|
| - out_info->subordinate_source.id = net::NetLog::Source::kInvalidId;
|
| - }
|
| + if (entry.type == net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB ||
|
| + entry.type == net::NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET) {
|
| + const net::NetLog::Source& source_dependency =
|
| + static_cast<net::NetLogSourceParameter*>(entry.params.get())->value();
|
| + AddReferenceToSourceDependency(source_dependency, out_info);
|
| }
|
|
|
| AddEntryToRequestInfo(entry, out_info);
|
| @@ -496,7 +380,6 @@
|
| // If the request has ended, move it to the graveyard.
|
| if (entry.type == net::NetLog::TYPE_REQUEST_ALIVE &&
|
| entry.phase == net::NetLog::PHASE_END) {
|
| - IntegrateSubordinateSource(out_info, true);
|
| if (StartsWithASCII(out_info->GetURL(), "chrome://", false)) {
|
| // Avoid sending "chrome://" requests to the graveyard, since it just
|
| // adds to clutter.
|
| @@ -508,53 +391,27 @@
|
| return ACTION_NONE;
|
| }
|
|
|
| -void PassiveLogCollector::RequestTracker::IntegrateSubordinateSource(
|
| - RequestInfo* info, bool clear_entries) const {
|
| - if (!info->subordinate_source.is_valid())
|
| - return;
|
| -
|
| - uint32 subordinate_id = info->subordinate_source.id;
|
| - switch (info->subordinate_source.type) {
|
| - case net::NetLog::SOURCE_CONNECT_JOB:
|
| - connect_job_tracker_->AppendLogEntries(info, subordinate_id);
|
| - break;
|
| - case net::NetLog::SOURCE_SOCKET:
|
| - socket_tracker_->AppendLogEntries(info, subordinate_id, clear_entries);
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -}
|
| -
|
| //----------------------------------------------------------------------------
|
| // InitProxyResolverTracker
|
| //----------------------------------------------------------------------------
|
|
|
| -PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker() {}
|
| +const size_t PassiveLogCollector::InitProxyResolverTracker::kMaxGraveyardSize =
|
| + 3;
|
|
|
| -void PassiveLogCollector::InitProxyResolverTracker::OnAddEntry(
|
| - const Entry& entry) {
|
| +PassiveLogCollector::InitProxyResolverTracker::InitProxyResolverTracker()
|
| + : RequestTrackerBase(kMaxGraveyardSize, NULL) {
|
| +}
|
| +
|
| +PassiveLogCollector::RequestTrackerBase::Action
|
| +PassiveLogCollector::InitProxyResolverTracker::DoAddEntry(
|
| + const Entry& entry, RequestInfo* out_info) {
|
| + AddEntryToRequestInfo(entry, out_info);
|
| if (entry.type == net::NetLog::TYPE_INIT_PROXY_RESOLVER &&
|
| - entry.phase == net::NetLog::PHASE_BEGIN) {
|
| - // If this is the start of a new InitProxyResolver, overwrite the old data.
|
| - entries_.clear();
|
| - entries_.push_back(entry);
|
| + entry.phase == net::NetLog::PHASE_END) {
|
| + return ACTION_MOVE_TO_GRAVEYARD;
|
| } else {
|
| - // Otherwise append it to the log for the latest InitProxyResolver.
|
| - if (!entries_.empty() && entries_[0].source.id != entry.source.id) {
|
| - // If this entry doesn't match what we think was the latest
|
| - // InitProxyResolver, drop it. (This shouldn't happen, but we will guard
|
| - // against it).
|
| - return;
|
| - }
|
| - entries_.push_back(entry);
|
| + return ACTION_NONE;
|
| }
|
| -
|
| - // Safety net: INIT_PROXY_RESOLVER shouldn't generate many messages, but in
|
| - // case something goes wrong, avoid exploding the memory usage.
|
| - if (entries_.size() > kMaxNumEntriesPerLog)
|
| - entries_.clear();
|
| }
|
|
|
| //----------------------------------------------------------------------------
|
| @@ -564,17 +421,17 @@
|
| const size_t PassiveLogCollector::SpdySessionTracker::kMaxGraveyardSize = 10;
|
|
|
| PassiveLogCollector::SpdySessionTracker::SpdySessionTracker()
|
| - : RequestTrackerBase(kMaxGraveyardSize) {
|
| + : RequestTrackerBase(kMaxGraveyardSize, NULL) {
|
| }
|
|
|
| PassiveLogCollector::RequestTrackerBase::Action
|
| PassiveLogCollector::SpdySessionTracker::DoAddEntry(const Entry& entry,
|
| RequestInfo* out_info) {
|
| + AddEntryToRequestInfo(entry, out_info);
|
| if (entry.type == net::NetLog::TYPE_SPDY_SESSION &&
|
| entry.phase == net::NetLog::PHASE_END) {
|
| return ACTION_MOVE_TO_GRAVEYARD;
|
| } else {
|
| - AddEntryToRequestInfo(entry, out_info);
|
| return ACTION_NONE;
|
| }
|
| }
|
|
|