diff options
-rw-r--r-- | chrome/browser/io_thread.cc | 46 | ||||
-rw-r--r-- | chrome/browser/io_thread.h | 4 | ||||
-rw-r--r-- | chrome/browser/net/passive_log_collector.cc | 38 | ||||
-rw-r--r-- | chrome/browser/net/passive_log_collector.h | 50 | ||||
-rw-r--r-- | net/base/net_log_event_type_list.h | 10 | ||||
-rw-r--r-- | net/base/net_log_source_type_list.h | 18 |
6 files changed, 141 insertions, 25 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index c451b25..90af284 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -74,6 +74,42 @@ net::HostResolver* CreateGlobalHostResolver() { return remapped_resolver; } +class LoggingNetworkChangeObserver + : public net::NetworkChangeNotifier::Observer { + public: + // |net_log| must remain valid throughout our lifetime. + explicit LoggingNetworkChangeObserver(net::NetLog* net_log) + : net_log_(net_log) { + net::NetworkChangeNotifier::AddObserver(this); + } + + ~LoggingNetworkChangeObserver() { + net::NetworkChangeNotifier::RemoveObserver(this); + } + + virtual void OnIPAddressChanged() { + LOG(INFO) << "Observed a change to the network IP addresses"; + + net::NetLog::Source global_source; + + // TODO(eroman): We shouldn't need to assign an ID to this source, since + // conceptually it is the "global event stream". However + // currently the javascript does a grouping on source id, so + // the display will look weird if we don't give it one. + global_source.id = net_log_->NextID(); + + net_log_->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSSES_CHANGED, + base::TimeTicks::Now(), + global_source, + net::NetLog::PHASE_NONE, + NULL); + } + + private: + net::NetLog* net_log_; + DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver); +}; + } // namespace // The IOThread object must outlive any tasks posted to the IO thread before the @@ -132,12 +168,22 @@ void IOThread::Init() { globals_ = new Globals; globals_->net_log.reset(new ChromeNetLog()); + + // Add an observer that will emit network change events to the ChromeNetLog. + // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be + // logging the network change before other IO thread consumers respond to it. + network_change_observer_.reset( + new LoggingNetworkChangeObserver(globals_->net_log.get())); + globals_->host_resolver = CreateGlobalHostResolver(); globals_->http_auth_handler_factory.reset(CreateDefaultAuthHandlerFactory( globals_->host_resolver)); } void IOThread::CleanUp() { + // This must be reset before the ChromeNetLog is destroyed. + network_change_observer_.reset(); + // If any child processes are still running, terminate them and // and delete the BrowserChildProcessHost instances to release whatever // IO thread only resources they are referencing. diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index f0ddca4..2df6b68 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h @@ -16,6 +16,7 @@ #include "chrome/common/net/predictor_common.h" #include "chrome/browser/net/connect_interceptor.h" #include "net/base/host_resolver.h" +#include "net/base/network_change_notifier.h" class ChromeNetLog; class ListValue; @@ -100,6 +101,9 @@ class IOThread : public BrowserProcessSubThread { // though |globals_| is reset by CleanUp(). scoped_ptr<ChromeNetLog> deferred_net_log_to_delete_; + // Observer that logs network changes to the ChromeNetLog. + scoped_ptr<net::NetworkChangeNotifier::Observer> network_change_observer_; + // These member variables are initialized by a task posted to the IO thread, // which gets posted by calling certain member functions of IOThread. diff --git a/chrome/browser/net/passive_log_collector.cc b/chrome/browser/net/passive_log_collector.cc index 165cabf..152d332 100644 --- a/chrome/browser/net/passive_log_collector.cc +++ b/chrome/browser/net/passive_log_collector.cc @@ -49,6 +49,7 @@ PassiveLogCollector::PassiveLogCollector() // Define the mapping between source types and the tracker objects. memset(&trackers_[0], 0, sizeof(trackers_)); + trackers_[net::NetLog::SOURCE_NONE] = &global_source_tracker_; 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_; @@ -74,12 +75,12 @@ void PassiveLogCollector::OnAddEntry( // Package the parameters into a single struct for convenience. Entry entry(num_events_seen_++, type, time, source, phase, params); - SourceTracker* tracker = GetTrackerForSourceType(entry.source.type); + SourceTrackerInterface* tracker = GetTrackerForSourceType(entry.source.type); if (tracker) tracker->OnAddEntry(entry); } -PassiveLogCollector::SourceTracker* +PassiveLogCollector::SourceTrackerInterface* PassiveLogCollector::GetTrackerForSourceType( net::NetLog::SourceType source_type) { DCHECK_LE(source_type, static_cast<int>(arraysize(trackers_))); @@ -126,6 +127,29 @@ std::string PassiveLogCollector::SourceInfo::GetURL() const { } //---------------------------------------------------------------------------- +// GlobalSourceTracker +//---------------------------------------------------------------------------- + +PassiveLogCollector::GlobalSourceTracker::GlobalSourceTracker() {} +PassiveLogCollector::GlobalSourceTracker::~GlobalSourceTracker() {} + +void PassiveLogCollector::GlobalSourceTracker::OnAddEntry(const Entry& entry) { + const size_t kMaxEntries = 30u; + entries_.push_back(entry); + if (entries_.size() > kMaxEntries) + entries_.pop_front(); +} + +void PassiveLogCollector::GlobalSourceTracker::Clear() { + entries_.clear(); +} + +void PassiveLogCollector::GlobalSourceTracker::AppendAllEntries( + EntryList* out) const { + out->insert(out->end(), entries_.begin(), entries_.end()); +} + +//---------------------------------------------------------------------------- // SourceTracker //---------------------------------------------------------------------------- @@ -280,8 +304,9 @@ void PassiveLogCollector::SourceTracker::AddReferenceToSourceDependency( const net::NetLog::Source& source, SourceInfo* info) { // Find the tracker which should be holding |source|. DCHECK(parent_); - SourceTracker* tracker = - parent_->GetTrackerForSourceType(source.type); + DCHECK_NE(source.type, net::NetLog::SOURCE_NONE); + SourceTracker* tracker = static_cast<SourceTracker*>( + parent_->GetTrackerForSourceType(source.type)); DCHECK(tracker); // Tell the owning tracker to increment the reference count of |source|. @@ -301,8 +326,9 @@ PassiveLogCollector::SourceTracker::ReleaseAllReferencesToDependencies( // Find the tracker which should be holding |source|. DCHECK(parent_); - SourceTracker* tracker = - parent_->GetTrackerForSourceType(source.type); + DCHECK_NE(source.type, net::NetLog::SOURCE_NONE); + SourceTracker* tracker = static_cast<SourceTracker*>( + parent_->GetTrackerForSourceType(source.type)); DCHECK(tracker); // Tell the owning tracker to decrement the reference count of |source|. diff --git a/chrome/browser/net/passive_log_collector.h b/chrome/browser/net/passive_log_collector.h index b927c0c..7615b28 100644 --- a/chrome/browser/net/passive_log_collector.h +++ b/chrome/browser/net/passive_log_collector.h @@ -90,9 +90,41 @@ class PassiveLogCollector : public ChromeNetLog::Observer { typedef std::vector<SourceInfo> SourceInfoList; + // Interface for consuming a NetLog entry. + class SourceTrackerInterface { + public: + virtual ~SourceTrackerInterface() {} + + virtual void OnAddEntry(const Entry& entry) = 0; + + // Clears all the passively logged data from this tracker. + virtual void Clear() = 0; + + // Appends all the captured entries to |out|. The ordering is undefined. + virtual void AppendAllEntries(EntryList* out) const = 0; + }; + + // This source tracker is intended for TYPE_NONE. All entries go into a + // circular buffer, and there is no concept of live/dead requests. + class GlobalSourceTracker : public SourceTrackerInterface { + public: + GlobalSourceTracker(); + ~GlobalSourceTracker(); + + // SourceTrackerInterface implementation: + virtual void OnAddEntry(const Entry& entry); + virtual void Clear(); + virtual void AppendAllEntries(EntryList* out) const; + + private: + typedef std::deque<Entry> CircularEntryList; + CircularEntryList entries_; + DISALLOW_COPY_AND_ASSIGN(GlobalSourceTracker); + }; + // This class stores and manages the passively logged information for // URLRequests/SocketStreams/ConnectJobs. - class SourceTracker { + class SourceTracker : public SourceTrackerInterface { public: // Creates a SourceTracker that will track at most |max_num_sources|. // Up to |max_graveyard_size| unreferenced sources will be kept around @@ -105,13 +137,10 @@ class PassiveLogCollector : public ChromeNetLog::Observer { virtual ~SourceTracker(); - void OnAddEntry(const Entry& entry); - - // Clears all the passively logged data from this tracker. - void Clear(); - - // Appends all the captured entries to |out|. The ordering is undefined. - void AppendAllEntries(EntryList* out) const; + // SourceTrackerInterface implementation: + virtual void OnAddEntry(const Entry& entry); + virtual void Clear(); + virtual void AppendAllEntries(EntryList* out) const; #ifdef UNIT_TEST // Helper used to inspect the current state by unit-tests. @@ -264,7 +293,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer { net::NetLog::EventParameters* params); // Returns the tracker to use for sources of type |source_type|, or NULL. - SourceTracker* GetTrackerForSourceType( + SourceTrackerInterface* GetTrackerForSourceType( net::NetLog::SourceType source_type); // Clears all of the passively logged data. @@ -280,6 +309,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer { FRIEND_TEST_ALL_PREFIXES(PassiveLogCollectorTest, HoldReferenceToDeletedSource); + GlobalSourceTracker global_source_tracker_; ConnectJobTracker connect_job_tracker_; SocketTracker socket_tracker_; RequestTracker url_request_tracker_; @@ -290,7 +320,7 @@ class PassiveLogCollector : public ChromeNetLog::Observer { // This array maps each NetLog::SourceType to one of the tracker instances // defined above. Use of this array avoid duplicating the list of trackers // elsewhere. - SourceTracker* trackers_[net::NetLog::SOURCE_COUNT]; + SourceTrackerInterface* trackers_[net::NetLog::SOURCE_COUNT]; // The count of how many events have flowed through this log. Used to set the // "order" field on captured events. diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h index cc26f5f..8c8df02 100644 --- a/net/base/net_log_event_type_list.h +++ b/net/base/net_log_event_type_list.h @@ -572,3 +572,13 @@ EVENT_TYPE(AUTH_PROXY) // The time spent authentication to the server. EVENT_TYPE(AUTH_SERVER) + +// ------------------------------------------------------------------------ +// Global events +// ------------------------------------------------------------------------ +// These are events which are not grouped by source id, as they have no +// context. + +// This event is emitted whenever NetworkChangeNotifier determines that the +// underlying network has changed. +EVENT_TYPE(NETWORK_IP_ADDRESSSES_CHANGED) diff --git a/net/base/net_log_source_type_list.h b/net/base/net_log_source_type_list.h index 6664c2d..d416f3f 100644 --- a/net/base/net_log_source_type_list.h +++ b/net/base/net_log_source_type_list.h @@ -5,13 +5,13 @@ // NOTE: No header guards are used, since this file is intended to be expanded // directly within a block where the SOURCE_TYPE macro is defined. -SOURCE_TYPE(NONE, -1) +// Used for global events which don't correspond to a particular entity. +SOURCE_TYPE(NONE, 0) +SOURCE_TYPE(URL_REQUEST, 1) +SOURCE_TYPE(SOCKET_STREAM, 2) +SOURCE_TYPE(INIT_PROXY_RESOLVER, 3) +SOURCE_TYPE(CONNECT_JOB, 4) +SOURCE_TYPE(SOCKET, 5) +SOURCE_TYPE(SPDY_SESSION, 6) -SOURCE_TYPE(URL_REQUEST, 0) -SOURCE_TYPE(SOCKET_STREAM, 1) -SOURCE_TYPE(INIT_PROXY_RESOLVER, 2) -SOURCE_TYPE(CONNECT_JOB, 3) -SOURCE_TYPE(SOCKET, 4) -SOURCE_TYPE(SPDY_SESSION, 5) - -SOURCE_TYPE(COUNT, 6) // Always keep this as the last entry. +SOURCE_TYPE(COUNT, 7) // Always keep this as the last entry. |