Chromium Code Reviews| Index: base/debug/trace_event_impl.h |
| diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h |
| index ca711dbd489108478394dc901ab40a78438a1a29..4e3c1250fe8099008485b0c8f5685a9655136d84 100644 |
| --- a/base/debug/trace_event_impl.h |
| +++ b/base/debug/trace_event_impl.h |
| @@ -16,6 +16,7 @@ |
| #include "base/memory/ref_counted_memory.h" |
| #include "base/observer_list.h" |
| #include "base/string_util.h" |
| +#include "base/synchronization/condition_variable.h" |
| #include "base/synchronization/lock.h" |
| #include "base/timer.h" |
| @@ -89,6 +90,7 @@ class BASE_EXPORT TraceEvent { |
| return parameter_copy_storage_.get(); |
| } |
| + const unsigned char* category_enabled() const { return category_enabled_; } |
| const char* name() const { return name_; } |
| private: |
| @@ -154,6 +156,16 @@ class BASE_EXPORT TraceResultBuffer { |
| class BASE_EXPORT TraceLog { |
| public: |
| + // Notification is a mask of one or more of the following events. |
| + enum Notification { |
|
ccameron
2012/08/21 01:06:34
This isn't treated as a bit mask (but rather as a
jbates
2012/08/23 22:45:28
Good catch, TraceControllerImpl::OnTraceNotificati
|
| + // The trace buffer does not flush dynamically, so when it fills up, |
| + // subsequent trace events will be dropped. This callback is generated when |
| + // the trace buffer is full. The callback must be thread safe. |
| + TRACE_BUFFER_FULL = 1 << 0, |
| + // A subscribed trace-event occurred. |
| + EVENT_WATCH_NOTIFICATION = 1 << 1 |
| + }; |
| + |
| static TraceLog* GetInstance(); |
| // Get set of known categories. This can change as new code paths are reached. |
| @@ -213,23 +225,21 @@ class BASE_EXPORT TraceLog { |
| float GetBufferPercentFull() const; |
| - // When enough events are collected, they are handed (in bulk) to |
| - // the output callback. If no callback is set, the output will be |
| - // silently dropped. The callback must be thread safe. The string format is |
| + // Set the thread-safe notification callback. The callback can occur at any |
| + // time. After calling SetNotificationCallback(NotificationCallback()) to |
| + // clear the callback, it is guaranteed that the old callback will no longer |
| + // be called. Warning: it is possible for the old callback to be called during |
| + // a call to SetNotificationCallback. |
| + typedef base::Callback<void(int)> NotificationCallback; |
| + void SetNotificationCallback(const NotificationCallback& cb); |
| + |
| + // Flush all collected events to the given output callback. The callback will |
| + // be called one or more times with IPC-bite-size chunks. The string format is |
| // undefined. Use TraceResultBuffer to convert one or more trace strings to |
| // JSON. |
| typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> |
| OutputCallback; |
| - void SetOutputCallback(const OutputCallback& cb); |
| - |
| - // The trace buffer does not flush dynamically, so when it fills up, |
| - // subsequent trace events will be dropped. This callback is generated when |
| - // the trace buffer is full. The callback must be thread safe. |
| - typedef base::Callback<void(void)> BufferFullCallback; |
| - void SetBufferFullCallback(const BufferFullCallback& cb); |
| - |
| - // Flushes all logged data to the callback. |
| - void Flush(); |
| + void Flush(const OutputCallback& cb); |
| // Called by TRACE_EVENT* macros, don't call this directly. |
| static const unsigned char* GetCategoryEnabled(const char* name); |
| @@ -263,6 +273,20 @@ class BASE_EXPORT TraceLog { |
| const void* id, |
| const std::string& extra); |
| + // After |num_occurrences| of given event have been seen on a particular |
| + // process since tracing was enabled, a notification will be fired. The event |
| + // count is not distributed across processes, so |num_occurrences| must occur |
| + // on one process. The watch event is automatically cleared after the |
| + // notification. |num_occurrences| must be greater than 0. |
| + // NOTE: If |num_occurrences| events have already occurred, the notification |
|
ccameron
2012/08/21 01:06:34
I have a preference for not supporting this semant
jbates
2012/08/23 22:45:28
This is important to catch the events that occur a
|
| + // will fire during the call to SetWatchEvent. |
| + void SetWatchEvent(const char* category_name, |
| + const char* event_name, |
| + int num_occurrences); |
| + // Cancel the watch event. If tracing is enabled, this may race with the |
| + // watch event notification firing. |
| + void CancelWatchEvent(); |
| + |
| int process_id() const { return process_id_; } |
| // Exposed for unittesting: |
| @@ -287,6 +311,25 @@ class BASE_EXPORT TraceLog { |
| // by the Singleton class. |
| friend struct StaticMemorySingletonTraits<TraceLog>; |
| + // Helper class for managing notification_thread_count_ and running |
| + // notification callbacks. |
| + class NotificationHelper { |
| + public: |
| + inline NotificationHelper(TraceLog* trace_log); |
| + inline ~NotificationHelper(); |
| + |
| + // Called only while TraceLog::lock_ is held. |
| + inline void AddNotificationWhileLocked(int notification); |
| + |
| + // Called only while TraceLog::lock_ is NOT held. |
| + inline void SendNotificationIfAny(); |
| + |
| + private: |
| + TraceLog* trace_log_; |
| + NotificationCallback callback_copy_; |
| + int notification_; |
| + }; |
| + |
| TraceLog(); |
| ~TraceLog(); |
| const unsigned char* GetCategoryEnabledInternal(const char* name); |
| @@ -297,8 +340,10 @@ class BASE_EXPORT TraceLog { |
| // synchronization. |
| Lock lock_; |
| bool enabled_; |
| - OutputCallback output_callback_; |
| - BufferFullCallback buffer_full_callback_; |
| + base::ConditionVariable notification_condition_; |
| + NotificationCallback notification_callback_; |
|
ccameron
2012/08/21 01:06:34
I see no concurrency issues with this implementati
jbates
2012/08/23 22:45:28
As discussed, added comments around the Notificati
|
| + // Number of threads that are have a copy of the notification callback. |
| + int notification_thread_count_; |
| std::vector<TraceEvent> logged_events_; |
| std::vector<std::string> included_categories_; |
| std::vector<std::string> excluded_categories_; |
| @@ -312,6 +357,11 @@ class BASE_EXPORT TraceLog { |
| int process_id_; |
| + // Allow tests to wake up when certain events occur. |
| + const unsigned char* watch_category_; |
| + std::string watch_event_name_; |
| + int watch_count_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(TraceLog); |
| }; |