File: src\libraries\System.Private.CoreLib\src\System\Diagnostics\Tracing\EventPipeEventDispatcher.Threads.cs
Web Access
Project: src\src\coreclr\System.Private.CoreLib\System.Private.CoreLib.csproj (System.Private.CoreLib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
 
namespace System.Diagnostics.Tracing
{
    internal sealed partial class EventPipeEventDispatcher
    {
        private void StartDispatchTask(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency)
        {
            Debug.Assert(Monitor.IsEntered(m_dispatchControlLock));
            Debug.Assert(sessionID != 0);
 
            m_dispatchTaskCancellationSource = new CancellationTokenSource();
            Task? previousDispatchTask = m_dispatchTask;
            m_dispatchTask = Task.Factory.StartNew(() => DispatchEventsToEventListeners(sessionID, syncTimeUtc, syncTimeQPC, timeQPCFrequency, previousDispatchTask, m_dispatchTaskCancellationSource.Token), CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }
 
        private void DispatchEventsToEventListeners(ulong sessionID, DateTime syncTimeUtc, long syncTimeQPC, long timeQPCFrequency, Task? previousDispatchTask, CancellationToken token)
        {
            Debug.Assert(sessionID != 0);
            previousDispatchTask?.Wait(CancellationToken.None);
 
            // Struct to fill with the call to GetNextEvent.
            while (!token.IsCancellationRequested)
            {
                bool eventsReceived = DispatchEventsToEventListenersOnce(sessionID, syncTimeUtc, syncTimeQPC, timeQPCFrequency, token);
 
                // Wait for more events.
                if (!token.IsCancellationRequested)
                {
                    if (!eventsReceived)
                    {
                        EventPipeInternal.WaitForSessionSignal(sessionID, Timeout.Infinite);
                    }
 
                    Thread.Sleep(10);
                }
            }
 
            // Wait for SignalSession() to be called before we call disable, otherwise
            // the SignalSession() call could be on a disabled session.
            SpinWait sw = default;
            while (Volatile.Read(ref m_sessionID) == sessionID)
            {
                sw.SpinOnce();
            }
 
            // Disable the old session. This can happen asynchronously since we aren't using the old session
            // anymore.
            EventPipeInternal.Disable(sessionID);
        }
    }
}