Refactored the duplicated code into a template method pattern
authorAndrew Au <andrewau@microsoft.com>
Thu, 25 Apr 2019 21:03:01 +0000 (14:03 -0700)
committerAndrew Au <cshung@gmail.com>
Fri, 26 Apr 2019 16:23:44 +0000 (09:23 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/3a559ad43022df53c0f1426c828a6c21f79dd5dd

src/coreclr/src/vm/eventpipe.cpp
src/coreclr/src/vm/eventpipe.h
src/coreclr/src/vm/eventpipeconfiguration.cpp
src/coreclr/src/vm/eventpipeconfiguration.h

index c8f2655..361fe83 100644 (file)
@@ -246,28 +246,21 @@ EventPipeSessionID EventPipe::Enable(
     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;
 }
@@ -356,18 +349,12 @@ void EventPipe::Disable(EventPipeSessionID id)
     // 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)
@@ -534,46 +521,39 @@ void WINAPI EventPipe::FlushTimer(PVOID parameter, BOOLEAN timerFired)
 
     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)
@@ -613,16 +593,12 @@ EventPipeProvider *EventPipe::CreateProvider(const SString &providerName, EventP
     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;
 }
@@ -930,4 +906,9 @@ EventPipeEventInstance *EventPipe::GetNextEvent()
     return pInstance;
 }
 
+/* static */ void EventPipe::InvokeCallback(EventPipeProviderCallbackData eventPipeProviderCallbackData)
+{
+    EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
+}
+
 #endif // FEATURE_PERFTRACING
index 6ddcc59..ad0e84e 100644 (file)
@@ -23,6 +23,16 @@ class EventPipeSession;
 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
@@ -234,7 +244,28 @@ public:
 
 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
 {
@@ -302,6 +333,24 @@ public:
     // 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);
index 9fb09b9..b32b94a 100644 (file)
@@ -92,18 +92,13 @@ void EventPipeConfiguration::Initialize()
     }
     CONTRACTL_END;
     
-    EventPipeProviderCallbackDataQueue eventPipeProviderCallbackDataQueue;
-    EventPipeProviderCallbackData eventPipeProviderCallbackData;
-    {
-        CrstHolder _crst(EventPipe::GetLock());
-
-        // Create the configuration provider.
-        m_pConfigProvider = CreateProvider(SL(s_configurationProviderName), NULL, NULL, &eventPipeProviderCallbackDataQueue);
-    }
-    while (eventPipeProviderCallbackDataQueue.TryDequeue(&eventPipeProviderCallbackData))
-    {
-        EventPipeProvider::InvokeCallback(eventPipeProviderCallbackData);
-    }
+    EventPipe::RunWithCallbackPostponed(
+        [&](EventPipeProviderCallbackDataQueue* pEventPipeProviderCallbackDataQueue)
+        {
+            // Create the configuration provider.
+            m_pConfigProvider = CreateProvider(SL(s_configurationProviderName), NULL, NULL, pEventPipeProviderCallbackDataQueue);
+        }
+    );
 
     // Create the metadata event.
     m_pMetadataEvent = m_pConfigProvider->AddEvent(
index e1e71e9..eb694ce 100644 (file)
@@ -16,45 +16,6 @@ class EventPipeProvider;
 class EventPipeSession;
 enum class EventPipeSessionType;
 
-enum class EventPipeEventLevel
-{
-    LogAlways,
-    Critical,
-    Error,
-    Warning,
-    Informational,
-    Verbose
-};
-
-struct EventPipeProviderCallbackData
-{
-    LPCWSTR pFilterData;
-    EventPipeCallback pCallbackFunction;
-    bool enabled;
-    INT64 keywords;
-    EventPipeEventLevel providerLevel;
-    void* pCallbackData;
-};
-
-struct EventPipeProviderCallbackDataNode
-{
-    EventPipeProviderCallbackData* value;
-    EventPipeProviderCallbackDataNode* prev;
-};
-
-class EventPipeProviderCallbackDataQueue
-{
-public:
-    EventPipeProviderCallbackDataQueue();
-
-    void Enqueue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
-
-    bool TryDequeue(EventPipeProviderCallbackData* pEventPipeProviderCallbackData);
-
-private:
-    SList<SListElem<EventPipeProviderCallbackData>> list;
-};
-
 class EventPipeConfiguration
 {
 public: