summaryrefslogtreecommitdiffstats
path: root/chrome/browser/net/chrome_net_log.h
diff options
context:
space:
mode:
authormmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-01 15:19:40 +0000
committermmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-01 15:19:40 +0000
commitb2fcd0e0c8850eda2135b6fe270af5f453682f23 (patch)
tree2858497a3551d59093a5dfd233bf3550d40a4e8d /chrome/browser/net/chrome_net_log.h
parent087a03f6aeded6397081304e191b1ac027b8e134 (diff)
downloadchromium_src-b2fcd0e0c8850eda2135b6fe270af5f453682f23.zip
chromium_src-b2fcd0e0c8850eda2135b6fe270af5f453682f23.tar.gz
chromium_src-b2fcd0e0c8850eda2135b6fe270af5f453682f23.tar.bz2
Update NetLog to be threadsafe.
The ChromeNetLog is now owned by the browser process, and passed to the IOThread on creation. NetLog entries can be added from any thread. Observers must be able to handle having log entries added from any thread. Observers can add/remove themselves on any thread. BUG=63334 TEST=None, yet Review URL: http://codereview.chromium.org/4118004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67851 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net/chrome_net_log.h')
-rw-r--r--chrome/browser/net/chrome_net_log.h109
1 files changed, 91 insertions, 18 deletions
diff --git a/chrome/browser/net/chrome_net_log.h b/chrome/browser/net/chrome_net_log.h
index aac09e6..f6a5c20 100644
--- a/chrome/browser/net/chrome_net_log.h
+++ b/chrome/browser/net/chrome_net_log.h
@@ -6,8 +6,13 @@
#define CHROME_BROWSER_NET_CHROME_NET_LOG_H_
#pragma once
+#include <vector>
+
+#include "base/atomicops.h"
+#include "base/lock.h"
#include "base/observer_list.h"
#include "base/scoped_ptr.h"
+#include "chrome/browser/browser_thread.h"
#include "net/base/net_log.h"
class LoadTimingObserver;
@@ -17,39 +22,85 @@ class PassiveLogCollector;
// ChromeNetLog is an implementation of NetLog that dispatches network log
// messages to a list of observers.
//
+// All methods are thread safe, with the exception that no ChromeNetLog or
+// ChromeNetLog::ThreadSafeObserver functions may be called by an observer's
+// OnAddEntry() method. Doing so will result in a deadlock.
+//
// By default, ChromeNetLog will attach the observer PassiveLogCollector which
// will keep track of recent request information (which used when displaying
// the about:net-internals page).
//
-// TODO(eroman): Move this default observer out of ChromeNetLog.
-//
class ChromeNetLog : public net::NetLog {
public:
+ // This structure encapsulates all of the parameters of an event,
+ // including an "order" field that identifies when it was captured relative
+ // to other events.
+ struct Entry {
+ Entry(uint32 order,
+ net::NetLog::EventType type,
+ const base::TimeTicks& time,
+ net::NetLog::Source source,
+ net::NetLog::EventPhase phase,
+ net::NetLog::EventParameters* params);
+ ~Entry();
+
+ uint32 order;
+ net::NetLog::EventType type;
+ base::TimeTicks time;
+ net::NetLog::Source source;
+ net::NetLog::EventPhase phase;
+ scoped_refptr<net::NetLog::EventParameters> params;
+ };
+
+ typedef std::vector<Entry> EntryList;
+
// Interface for observing the events logged by the network stack.
- class Observer {
+ class ThreadSafeObserver {
public:
// Constructs an observer that wants to see network events, with
- // the specified minimum event granularity.
+ // the specified minimum event granularity. A ThreadSafeObserver can only
+ // observe a single ChromeNetLog at a time.
//
// Typical observers should specify LOG_BASIC.
//
// Observers that need to see the full granularity of events can
// specify LOG_ALL. However doing so will have performance consequences,
- // and may cause PassiveLogCollector to use more memory than anticiapted.
- explicit Observer(LogLevel log_level);
+ // and may cause PassiveLogCollector to use more memory than anticipated.
+ //
+ // Observers will be called on the same thread an entry is added on,
+ // and are responsible for ensuring their own thread safety.
+ explicit ThreadSafeObserver(LogLevel log_level);
+
+ virtual ~ThreadSafeObserver();
- virtual ~Observer() {}
+ // This method will be called on the thread that the event occurs on. It
+ // is the responsibility of the observer to handle it in a thread safe
+ // manner.
+ //
+ // It is illegal for an Observer to call any ChromeNetLog or
+ // ChromeNetLog::ThreadSafeObserver functions in response to a call to
+ // OnAddEntry.
virtual void OnAddEntry(EventType type,
const base::TimeTicks& time,
const Source& source,
EventPhase phase,
EventParameters* params) = 0;
LogLevel log_level() const;
+
protected:
- void set_log_level(LogLevel log_level);
+ void AssertNetLogLockAcquired() const;
+
+ // Can only be called when actively observing a ChromeNetLog.
+ void SetLogLevel(LogLevel log_level);
+
+ // ChromeNetLog currently being observed, if any. Set by ChromeNetLog's
+ // AddObserver and RemoveObserver methods.
+ ChromeNetLog* net_log_;
+
private:
+ friend class ChromeNetLog;
LogLevel log_level_;
- DISALLOW_COPY_AND_ASSIGN(Observer);
+ DISALLOW_COPY_AND_ASSIGN(ThreadSafeObserver);
};
ChromeNetLog();
@@ -64,26 +115,48 @@ class ChromeNetLog : public net::NetLog {
virtual uint32 NextID();
virtual LogLevel GetLogLevel() const;
- void AddObserver(Observer* observer);
- void RemoveObserver(Observer* observer);
+ void AddObserver(ThreadSafeObserver* observer);
+ void RemoveObserver(ThreadSafeObserver* observer);
- PassiveLogCollector* passive_collector() {
- return passive_collector_.get();
- }
+ // Adds |observer| and writes all passively captured events to
+ // |passive_entries|. Guarantees that no events in |passive_entries| will be
+ // sent to |observer| and all future events that have yet been sent to the
+ // PassiveLogCollector will be sent to |observer|.
+ void AddObserverAndGetAllPassivelyCapturedEvents(ThreadSafeObserver* observer,
+ EntryList* passive_entries);
+
+ void GetAllPassivelyCapturedEvents(EntryList* passive_entries);
+
+ void ClearAllPassivelyCapturedEvents();
LoadTimingObserver* load_timing_observer() {
return load_timing_observer_.get();
}
private:
- uint32 next_id_;
+ void AddObserverWhileLockHeld(ThreadSafeObserver* observer);
+
+ // Called whenever an observer is added or removed, or changes its log level.
+ // Must have acquired |lock_| prior to calling.
+ void UpdateLogLevel_();
+
+ // |lock_| protects access to |observers_| and, indirectly, to
+ // |passive_collector_|. Should not be acquired by observers.
+ Lock lock_;
+
+ // Last assigned source ID. Incremented to get the next one.
+ base::subtle::Atomic32 last_id_;
+
+ base::subtle::Atomic32 log_level_;
+
+ // Not thread safe. Must only be used when |lock_| is acquired.
scoped_ptr<PassiveLogCollector> passive_collector_;
+
scoped_ptr<LoadTimingObserver> load_timing_observer_;
scoped_ptr<NetLogLogger> net_log_logger_;
- // Note that this needs to be "mutable" so we can iterate over the observer
- // list in GetLogLevel().
- mutable ObserverList<Observer, true> observers_;
+ // |lock_| must be acquired whenever reading or writing to this.
+ ObserverList<ThreadSafeObserver, true> observers_;
DISALLOW_COPY_AND_ASSIGN(ChromeNetLog);
};