diff options
author | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-06 15:39:40 +0000 |
---|---|---|
committer | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-06 15:39:40 +0000 |
commit | ba50d192694e3bbdd99d153205e7fcef236abf8a (patch) | |
tree | d4621c1cbad3e63cd87c40689c0ae5daaafab1fe /base/win/event_trace_consumer.h | |
parent | f2505c82c17948056214d3437d53620610fba837 (diff) | |
download | chromium_src-ba50d192694e3bbdd99d153205e7fcef236abf8a.zip chromium_src-ba50d192694e3bbdd99d153205e7fcef236abf8a.tar.gz chromium_src-ba50d192694e3bbdd99d153205e7fcef236abf8a.tar.bz2 |
Move Windows-specific Event Tracing for Windows implementation to base/win.
fix users of same.
BUG=none
TEST=unittests
Review URL: http://codereview.chromium.org/4517004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65310 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/win/event_trace_consumer.h')
-rw-r--r-- | base/win/event_trace_consumer.h | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/base/win/event_trace_consumer.h b/base/win/event_trace_consumer.h new file mode 100644 index 0000000..1ceb9ee --- /dev/null +++ b/base/win/event_trace_consumer.h @@ -0,0 +1,150 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Declaration of a Windows event trace consumer base class. +#ifndef BASE_WIN_EVENT_TRACE_CONSUMER_H_ +#define BASE_WIN_EVENT_TRACE_CONSUMER_H_ +#pragma once + +#include <windows.h> +#include <wmistr.h> +#include <evntrace.h> +#include <vector> +#include "base/basictypes.h" + +namespace base { +namespace win { + +// This class is a base class that makes it easier to consume events +// from realtime or file sessions. Concrete consumers need to sublass +// a specialization of this class and override the ProcessEvent and/or +// the ProcessBuffer methods to implement the event consumption logic. +// Usage might look like: +// class MyConsumer: public EtwTraceConsumerBase<MyConsumer, 1> { +// protected: +// static VOID WINAPI ProcessEvent(PEVENT_TRACE event); +// }; +// +// MyConsumer consumer; +// consumer.OpenFileSession(file_path); +// consumer.Consume(); +template <class ImplClass> +class EtwTraceConsumerBase { + public: + // Constructs a closed consumer. + EtwTraceConsumerBase() { + } + + ~EtwTraceConsumerBase() { + Close(); + } + + // Opens the named realtime session, which must be existent. + // Note: You can use OpenRealtimeSession or OpenFileSession + // to open as many as MAXIMUM_WAIT_OBJECTS (63) sessions at + // any one time, though only one of them may be a realtime + // session. + HRESULT OpenRealtimeSession(const wchar_t* session_name); + + // Opens the event trace log in "file_name", which must be a full or + // relative path to an existing event trace log file. + // Note: You can use OpenRealtimeSession or OpenFileSession + // to open as many as kNumSessions at any one time. + HRESULT OpenFileSession(const wchar_t* file_name); + + // Consume all open sessions from beginning to end. + HRESULT Consume(); + + // Close all open sessions. + HRESULT Close(); + + protected: + // Override in subclasses to handle events. + static void ProcessEvent(EVENT_TRACE* event) { + } + // Override in subclasses to handle buffers. + static bool ProcessBuffer(EVENT_TRACE_LOGFILE* buffer) { + return true; // keep going + } + + protected: + // Currently open sessions. + std::vector<TRACEHANDLE> trace_handles_; + + private: + // These delegate to ImplClass callbacks with saner signatures. + static void WINAPI ProcessEventCallback(EVENT_TRACE* event) { + ImplClass::ProcessEvent(event); + } + static ULONG WINAPI ProcessBufferCallback(PEVENT_TRACE_LOGFILE buffer) { + return ImplClass::ProcessBuffer(buffer); + } + + DISALLOW_COPY_AND_ASSIGN(EtwTraceConsumerBase); +}; + +template <class ImplClass> inline +HRESULT EtwTraceConsumerBase<ImplClass>::OpenRealtimeSession( + const wchar_t* session_name) { + EVENT_TRACE_LOGFILE logfile = {}; + logfile.LoggerName = const_cast<wchar_t*>(session_name); + logfile.LogFileMode = EVENT_TRACE_REAL_TIME_MODE; + logfile.BufferCallback = &ProcessBufferCallback; + logfile.EventCallback = &ProcessEventCallback; + logfile.Context = this; + TRACEHANDLE trace_handle = ::OpenTrace(&logfile); + if (reinterpret_cast<TRACEHANDLE>(INVALID_HANDLE_VALUE) == trace_handle) + return HRESULT_FROM_WIN32(::GetLastError()); + + trace_handles_.push_back(trace_handle); + return S_OK; +} + +template <class ImplClass> inline +HRESULT EtwTraceConsumerBase<ImplClass>::OpenFileSession( + const wchar_t* file_name) { + EVENT_TRACE_LOGFILE logfile = {}; + logfile.LogFileName = const_cast<wchar_t*>(file_name); + logfile.BufferCallback = &ProcessBufferCallback; + logfile.EventCallback = &ProcessEventCallback; + logfile.Context = this; + TRACEHANDLE trace_handle = ::OpenTrace(&logfile); + if (reinterpret_cast<TRACEHANDLE>(INVALID_HANDLE_VALUE) == trace_handle) + return HRESULT_FROM_WIN32(::GetLastError()); + + trace_handles_.push_back(trace_handle); + return S_OK; +} + +template <class ImplClass> inline +HRESULT EtwTraceConsumerBase<ImplClass>::Consume() { + ULONG err = ::ProcessTrace(&trace_handles_[0], + trace_handles_.size(), + NULL, + NULL); + return HRESULT_FROM_WIN32(err); +} + +template <class ImplClass> inline +HRESULT EtwTraceConsumerBase<ImplClass>::Close() { + HRESULT hr = S_OK; + for (size_t i = 0; i < trace_handles_.size(); ++i) { + if (NULL != trace_handles_[i]) { + ULONG ret = ::CloseTrace(trace_handles_[i]); + trace_handles_[i] = NULL; + + if (FAILED(HRESULT_FROM_WIN32(ret))) + hr = HRESULT_FROM_WIN32(ret); + } + + trace_handles_.clear(); + } + + return hr; +} + +} // namespace win +} // namespace base + +#endif // BASE_WIN_EVENT_TRACE_CONSUMER_H_ |