CONTRACTL_END;
EventPipeSessionID sessionId;
- EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
- EventPipeProviderCallbackData eventPipeProviderCallbackData;
- {
- // Take the lock before enabling tracing.
- CrstHolder _crst(GetLock());
-
- // Create a new session.
- SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds);
- EventPipeSession *pSession = s_pConfig->CreateSession(
- (strOutputPath != NULL) ? EventPipeSessionType::File : EventPipeSessionType::Streaming,
- circularBufferSizeInMB,
- pProviders,
- numProviders);
-
- // Enable the session.
- sessionId = Enable(strOutputPath, pSession, sessionType, pStream, &eventPipeProviderCallbackDataQueue);
- }
-
- while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
- {
- EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
- }
+ EventPipe::RunWithCallbackPostponed(
+ [&](EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
+ {
+ // Create a new session.
+ SampleProfiler::SetSamplingRate((unsigned long)profilerSamplingRateInNanoseconds);
+ EventPipeSession *pSession = s_pConfig->CreateSession(
+ (strOutputPath != NULL) ? EventPipeSessionType::File : EventPipeSessionType::Streaming,
+ circularBufferSizeInMB,
+ pProviders,
+ numProviders);
+
+ // Enable the session.
+ sessionId = Enable(strOutputPath, pSession, sessionType, pStream, pEventPipeProviderCallbackDataQueue);
+ }
+ );
return sessionId;
}
// Don't block GC during clean-up.
GCX_PREEMP();
- EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
- EventPipeProviderCallbackData eventPipeProviderCallbackData;
- {
- // Take the lock before disabling tracing.
- CrstHolder _crst(GetLock());
- DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession), &eventPipeProviderCallbackDataQueue);
- }
-
- while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
- {
- EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
- }
+ EventPipe::RunWithCallbackPostponed(
+ [&](EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
+ {
+ DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession), pEventPipeProviderCallbackDataQueue);
+ }
+ );
}
void EventPipe::DisableInternal(EventPipeSessionID id, EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
GCX_PREEMP();
- EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
- EventPipeProviderCallbackData eventPipeProviderCallbackData;
- {
- // Take the lock control lock to make sure that tracing isn't disabled during this operation.
- CrstHolder _crst(GetLock());
+ EventPipe::RunWithCallbackPostponed(
+ [&](EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
+ {
+ if (s_pSession == nullptr || s_pFile == nullptr)
+ return;
- if (s_pSession == nullptr || s_pFile == nullptr)
- return;
+ // Make sure that we should actually switch files.
+ if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::IpcStream)
+ return;
- // Make sure that we should actually switch files.
- if (!Enabled() || s_pSession->GetSessionType() != EventPipeSessionType::IpcStream)
- return;
-
- if (CLRGetTickCount64() > (s_lastFlushSwitchTime + 100))
- {
- // Get the current time stamp.
- // WriteAllBuffersToFile will use this to ensure that no events after
- // the current timestamp are written into the file.
- LARGE_INTEGER stopTimeStamp;
- QueryPerformanceCounter(&stopTimeStamp);
- s_pBufferManager->WriteAllBuffersToFile(s_pFile, stopTimeStamp);
-
- s_lastFlushSwitchTime = CLRGetTickCount64();
- }
+ if (CLRGetTickCount64() > (s_lastFlushSwitchTime + 100))
+ {
+ // Get the current time stamp.
+ // WriteAllBuffersToFile will use this to ensure that no events after
+ // the current timestamp are written into the file.
+ LARGE_INTEGER stopTimeStamp;
+ QueryPerformanceCounter(&stopTimeStamp);
+ s_pBufferManager->WriteAllBuffersToFile(s_pFile, stopTimeStamp);
+
+ s_lastFlushSwitchTime = CLRGetTickCount64();
+ }
- if (s_pFile->HasErrors())
- {
- EX_TRY
+ if (s_pFile->HasErrors())
{
- DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession), &eventPipeProviderCallbackDataQueue);
+ EX_TRY
+ {
+ DisableInternal(reinterpret_cast<EventPipeSessionID>(s_pSession), pEventPipeProviderCallbackDataQueue);
+ }
+ EX_CATCH {}
+ EX_END_CATCH(SwallowAllExceptions);
}
- EX_CATCH {}
- EX_END_CATCH(SwallowAllExceptions);
}
- }
-
- while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
- {
- EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
- }
+ );
}
EventPipeSession *EventPipe::GetSession(EventPipeSessionID id)
CONTRACTL_END;
EventPipeProvider *pProvider = NULL;
- EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
- EventPipeProviderCallbackData eventPipeProviderCallbackData;
- {
- CrstHolder _crst(GetLock());
- pProvider = EventPipe::CreateProvider(providerName, pCallbackFunction, pCallbackData, &eventPipeProviderCallbackDataQueue);
- }
- while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
- {
- EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
- }
+ EventPipe::RunWithCallbackPostponed(
+ [&](EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
+ {
+ pProvider = EventPipe::CreateProvider(providerName, pCallbackFunction, pCallbackData, pEventPipeProviderCallbackDataQueue);
+ }
+ );
return pProvider;
}
return pInstance;
}
+/* static */ void EventPipe::InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData)
+{
+ EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
+}
+
#endif // FEATURE_PERFTRACING
class IpcStream;
enum class EventPipeSessionType;
+enum class EventPipeEventLevel
+{
+ LogAlways,
+ Critical,
+ Error,
+ Warning,
+ Informational,
+ Verbose
+};
+
// EVENT_FILTER_DESCRIPTOR (This type does not exist on non-Windows platforms.)
// https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/ns-evntprov-_event_filter_descriptor
// The structure supplements the event provider, level, and keyword data that
typedef UINT64 EventPipeSessionID;
-class EventPipeProviderCallbackDataQueue;
+struct EventPipeProviderCallbackData
+{
+ LPCWSTR pFilterData;
+ EventPipeCallback pCallbackFunction;
+ bool enabled;
+ INT64 keywords;
+ EventPipeEventLevel providerLevel;
+ void* pCallbackData;
+};
+
+class EventPipeProviderCallbackDataQueue
+{
+public:
+ EventPipeProviderCallbackDataQueue();
+
+ void Enqueue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
+
+ bool TryDequeue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
+
+private:
+ SList<SListElem<EventPipeProviderCallbackData>> list;
+};
class EventPipe
{
// Get next event.
static EventPipeEventInstance *GetNextEvent();
+ template<class T>
+ static void RunWithCallbackPostponed(T f)
+ {
+ EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
+ EventPipeProviderCallbackData eventPipeProviderCallbackData;
+ {
+ CrstHolder _crst(GetLock());
+ f(&eventPipeProviderCallbackDataQueue);
+ }
+
+ while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
+ {
+ EventPipe::InvokeCallback(eventPipeProviderCallbackData);
+ }
+ }
+
+ static void InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData);
+
private:
// The counterpart to WriteEvent which after the payload is constructed
static void WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload &payload, LPCGUID pActivityId = NULL, LPCGUID pRelatedActivityId = NULL);