// Disable pSession tracing.
s_config.Disable(*pSession, pEventPipeProviderCallbackDataQueue);
- // At this point, we should not be writing events to this session anymore
- // This is a good time to remove the session from the array.
- _ASSERTE(s_pSessions[pSession->GetIndex()] == pSession);
-
- // Remove the session from the array, and mask.
- s_pSessions[pSession->GetIndex()].Store(nullptr);
-
pSession->Disable(); // Suspend EventPipeBufferManager, and remove providers.
// Do rundown before fully stopping the session.
--s_numberOfSessions;
+ // At this point, we should not be writing events to this session anymore
+ // This is a good time to remove the session from the array.
+ _ASSERTE(s_pSessions[pSession->GetIndex()] == pSession);
+
+ // Remove the session from the array, and mask.
+ s_pSessions[pSession->GetIndex()].Store(nullptr);
+
// Write a final sequence point to the file now that all events have
// been emitted.
pSession->WriteSequencePointUnbuffered();
m_pProviderList->InsertTail(new SListElem<EventPipeProvider *>(&provider));
}
+ INT64 keywordForAllSessions;
+ EventPipeEventLevel levelForAllSessions;
+ ComputeKeywordAndLevel(provider, /* out */ keywordForAllSessions, /* out */ levelForAllSessions);
+
EventPipe::ForEachSession([&](EventPipeSession &session) {
// Set the provider configuration and enable it if it has been requested by a session.
EventPipeSessionProvider *pSessionProvider = GetSessionProvider(session, &provider);
return;
EventPipeProviderCallbackData eventPipeProviderCallbackData = provider.SetConfiguration(
+ keywordForAllSessions,
+ levelForAllSessions,
session.GetMask(),
pSessionProvider->GetKeywords(),
pSessionProvider->GetLevel(),
return NULL;
}
-EventPipeSessionProvider *EventPipeConfiguration::GetSessionProvider(const EventPipeSession &session, EventPipeProvider *pProvider)
+EventPipeSessionProvider *EventPipeConfiguration::GetSessionProvider(const EventPipeSession &session, const EventPipeProvider *pProvider) const
{
CONTRACTL
{
return session.GetSessionProvider(pProvider);
}
+void EventPipeConfiguration::ComputeKeywordAndLevel(const EventPipeProvider& provider, INT64& keywordForAllSessions, EventPipeEventLevel& levelForAllSessions) const
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ PRECONDITION(EventPipe::IsLockOwnedByCurrentThread());
+ }
+ CONTRACTL_END;
+ keywordForAllSessions = 0;
+ levelForAllSessions = EventPipeEventLevel::LogAlways;
+ EventPipe::ForEachSession([&](EventPipeSession &session) {
+ EventPipeSessionProvider *pSessionProvider = GetSessionProvider(session, &provider);
+ if (pSessionProvider != nullptr)
+ {
+ INT64 sessionKeyword = pSessionProvider->GetKeywords();
+ EventPipeEventLevel sessionLevel = pSessionProvider->GetLevel();
+ keywordForAllSessions = keywordForAllSessions | sessionKeyword;
+ levelForAllSessions = (sessionLevel > levelForAllSessions) ? sessionLevel : levelForAllSessions;
+ }
+ });
+}
+
void EventPipeConfiguration::Enable(EventPipeSession &session, EventPipeProviderCallbackDataQueue *pEventPipeProviderCallbackDataQueue)
{
CONTRACTL
EventPipeSessionProvider *pSessionProvider = GetSessionProvider(session, pProvider);
if (pSessionProvider != NULL)
{
+ INT64 keywordForAllSessions;
+ EventPipeEventLevel levelForAllSessions;
+ ComputeKeywordAndLevel(*pProvider, /* out */ keywordForAllSessions, /* out */ levelForAllSessions);
+
EventPipeProviderCallbackData eventPipeProviderCallbackData =
pProvider->SetConfiguration(
+ keywordForAllSessions,
+ levelForAllSessions,
session.GetMask(),
pSessionProvider->GetKeywords(),
pSessionProvider->GetLevel(),
while (pElem != NULL)
{
EventPipeProvider *pProvider = pElem->GetValue();
-
if (pProvider->IsEnabled(session.GetMask()))
{
EventPipeSessionProvider *pSessionProvider = GetSessionProvider(session, pProvider);
if (pSessionProvider != nullptr)
{
+ INT64 keywordForAllSessions;
+ EventPipeEventLevel levelForAllSessions;
+ ComputeKeywordAndLevel(*pProvider, /* out */ keywordForAllSessions, /* out */ levelForAllSessions);
+
EventPipeProviderCallbackData eventPipeProviderCallbackData = pProvider->UnsetConfiguration(
+ keywordForAllSessions,
+ levelForAllSessions,
session.GetMask(),
pSessionProvider->GetKeywords(),
pSessionProvider->GetLevel(),
EventPipeProvider *GetProviderNoLock(const SString &providerID);
// Get the enabled provider.
- EventPipeSessionProvider *GetSessionProvider(const EventPipeSession &session, EventPipeProvider *pProvider);
+ EventPipeSessionProvider *GetSessionProvider(const EventPipeSession &session, const EventPipeProvider *pProvider) const;
+
+ // Compute the keyword union and maximum level for a provider across all sessions
+ void ComputeKeywordAndLevel(const EventPipeProvider& provider, INT64& keywordsForAllSessions, EventPipeEventLevel& levelForAllSessions) const;
// The list of event pipe providers.
SList<SListElem<EventPipeProvider *>> *m_pProviderList = nullptr;
}
EventPipeProviderCallbackData EventPipeProvider::SetConfiguration(
+ INT64 keywordsForAllSessions,
+ EventPipeEventLevel providerLevelForAllSessions,
uint64_t sessionMask,
INT64 keywords,
EventPipeEventLevel providerLevel,
m_sessions |= sessionMask;
- // Set Keywords to be the union of all keywords
- m_keywords |= keywords;
+ m_keywords = keywordsForAllSessions;
+ m_providerLevel = providerLevelForAllSessions;
- // Set the provider level to "Log Always" or the biggest verbosity.
- m_providerLevel = (providerLevel < m_providerLevel) ? m_providerLevel : providerLevel;
-
- RefreshAllEvents(sessionMask, keywords, providerLevel);
+ RefreshAllEvents();
return PrepareCallbackData(keywords, providerLevel, pFilterData);
}
EventPipeProviderCallbackData EventPipeProvider::UnsetConfiguration(
- uint64_t sessionMask,
- INT64 keywords,
- EventPipeEventLevel providerLevel,
- LPCWSTR pFilterData)
+ INT64 keywordsForAllSessions,
+ EventPipeEventLevel providerLevelForAllSessions,
+ uint64_t sessionMask,
+ INT64 keywords,
+ EventPipeEventLevel providerLevel,
+ LPCWSTR pFilterData)
{
CONTRACTL
{
if (m_sessions & sessionMask)
m_sessions &= ~sessionMask;
+
+ m_keywords = keywordsForAllSessions;
+ m_providerLevel = providerLevelForAllSessions;
+
+ RefreshAllEvents();
return PrepareCallbackData(keywords, providerLevel, pFilterData);
}
m_deleteDeferred = true;
}
-void EventPipeProvider::RefreshAllEvents(
- uint64_t sessionMask,
- INT64 keywords,
- EventPipeEventLevel providerLevel)
+void EventPipeProvider::RefreshAllEvents()
{
CONTRACTL
{
// Set the provider configuration (enable sets of events).
// This is called by EventPipeConfiguration.
EventPipeProviderCallbackData SetConfiguration(
+ INT64 keywordsForAllSessions,
+ EventPipeEventLevel providerLevelForAllSessions,
uint64_t sessionMask,
INT64 keywords,
EventPipeEventLevel providerLevel,
// Unset the provider configuration for the specified session (disable sets of events).
// This is called by EventPipeConfiguration.
EventPipeProviderCallbackData UnsetConfiguration(
+ INT64 keywordsForAllSessions,
+ EventPipeEventLevel providerLevelForAllSessions,
uint64_t sessionMask,
INT64 keywords,
EventPipeEventLevel providerLevel,
LPCWSTR pFilterData);
// Refresh the runtime state of all events.
- void RefreshAllEvents(
- uint64_t sessionMask,
- INT64 keywords,
- EventPipeEventLevel providerLevel);
+ void RefreshAllEvents();
// Prepare the data required for invoking callback
EventPipeProviderCallbackData PrepareCallbackData(
m_pProviderList->AddSessionProvider(pProvider);
}
-EventPipeSessionProvider *EventPipeSession::GetSessionProvider(EventPipeProvider *pProvider) const
+EventPipeSessionProvider *EventPipeSession::GetSessionProvider(const EventPipeProvider *pProvider) const
{
CONTRACTL
{
void AddSessionProvider(EventPipeSessionProvider *pProvider);
// Get the session provider for the specified provider if present.
- EventPipeSessionProvider* GetSessionProvider(EventPipeProvider *pProvider) const;
+ EventPipeSessionProvider* GetSessionProvider(const EventPipeProvider *pProvider) const;
bool WriteAllBuffersToFile();
m_pProviders->InsertTail(new SListElem<EventPipeSessionProvider *>(pProvider));
}
-EventPipeSessionProvider *EventPipeSessionProviderList::GetSessionProvider(EventPipeProvider *pProvider) const
+EventPipeSessionProvider *EventPipeSessionProviderList::GetSessionProvider(const EventPipeProvider *pProvider) const
{
CONTRACTL
{
// Get the session provider for the specified provider.
// Return NULL if one doesn't exist.
- EventPipeSessionProvider* GetSessionProvider(EventPipeProvider *pProvider) const;
+ EventPipeSessionProvider* GetSessionProvider(const EventPipeProvider *pProvider) const;
// Returns true if the list is empty.
bool IsEmpty() const;