public override ProcessTokenEntry Clone()
        {
            ThreadTokenEntry thread = (ThreadTokenEntry)base.Clone();

            thread.ThreadToken = ThreadToken.Duplicate();
            return(thread);
        }
        public ThreadInfo()
        {
            m_Packet             = new ThreadInfoPacket();
            m_Packet.ThreadIndex = ThreadToken.GetCurrentThreadIndex(); // Each ThreadInfo we create gets a unique index value.

            Thread thread = Thread.CurrentThread;

            m_Packet.ThreadId           = thread.ManagedThreadId;      // These can get recycled, so they aren't domain-lifetime unique.
            m_Packet.ThreadName         = thread.Name ?? string.Empty; // prevent null, but let empty name pass through
            m_Packet.DomainId           = 0;
            m_Packet.DomainName         = string.Empty;
            m_Packet.IsBackground       = thread.IsBackground;
            m_Packet.IsThreadPoolThread = false;
            m_ThreadInstance            = 0;
            m_Caption     = null;
            m_Description = null;
        }
            /// <summary>
            /// Register the current thread so that we can detect when it no longer exists, and return its unique ThreadIndex.
            /// </summary>
            /// <returns>The unique ThreadIndex value assigned to the current thread.</returns>
            internal static int GetCurrentThreadIndex()
            {
                int index;

                if (t_ThreadToken == null)
                {
                    index = GetNextThreadIndex();
                    ThreadToken newToken = new ThreadToken(index);
                    lock (MapLock)
                    {
                        ThreadTokenMap[index] = new WeakReference(newToken);
                    }
                    t_ThreadToken = newToken;
                }
                else
                {
                    // This shouldn't normally happen, but if they call us again from the same thread....
                    index = t_ThreadToken.ThreadIndex;
                }

                return(index);
            }
 /// <summary>
 /// Returns the unique threadIndex value assigned to the current thread.
 /// </summary>
 /// <returns>The threadIndex value for the current thread which is unique across the life of this log session.</returns>
 internal static int GetCurrentThreadIndex()
 {
     return(ThreadToken.GetCurrentThreadIndex());
 }
 /// <summary>
 /// Is the thread with the specified threadIndex still active in memory?  Only legitimate within the session where
 /// the thread was running.  Do not query this for playback outside the original running session.
 /// </summary>
 /// <param name="threadIndex">The unique ThreadIndex value which the Agent assigned to the thread in question.</param>
 /// <returns>Reports true if the managed thread which was assigned the specified threadIndex still exists
 /// or has not yet garbage collected its [ThreadStatic] variables.  Reports false after garbage collection.</returns>
 internal static bool IsThreadStillAlive(int threadIndex)
 {
     return(ThreadToken.IsThreadStillAlive(threadIndex));
 }
 public override void Dispose()
 {
     ThreadToken?.Dispose();
     base.Dispose();
 }