/ src / modules / MouseWithoutBorders / App / Core / Thread.cs
Thread.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System.Collections.Generic;
  6  using System.Diagnostics;
  7  using System.Globalization;
  8  using System.Threading;
  9  
 10  // <summary>
 11  //     Logging.
 12  // </summary>
 13  // <history>
 14  //     2008 created by Truong Do (ductdo).
 15  //     2009-... modified by Truong Do (TruongDo).
 16  //     2023- Included in PowerToys.
 17  // </history>
 18  namespace MouseWithoutBorders.Core;
 19  
 20  internal sealed class Thread
 21  {
 22      private static readonly Lock ThreadsLock = new();
 23      private static List<System.Threading.Thread> threads;
 24  
 25      private readonly System.Threading.Thread thread;
 26  
 27      internal Thread(ThreadStart callback, string name)
 28      {
 29          UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name });
 30      }
 31  
 32      internal Thread(ParameterizedThreadStart callback, string name)
 33      {
 34          UpdateThreads(thread = new System.Threading.Thread(callback) { Name = name });
 35      }
 36  
 37      internal static void UpdateThreads(System.Threading.Thread thread)
 38      {
 39          lock (ThreadsLock)
 40          {
 41              bool found = false;
 42              List<System.Threading.Thread> toBeRemovedThreads = new();
 43              threads ??= new List<System.Threading.Thread>();
 44  
 45              foreach (System.Threading.Thread t in threads)
 46              {
 47                  if (!t.IsAlive)
 48                  {
 49                      toBeRemovedThreads.Add(t);
 50                  }
 51                  else if (t.ManagedThreadId == thread.ManagedThreadId)
 52                  {
 53                      found = true;
 54                  }
 55              }
 56  
 57              foreach (System.Threading.Thread t in toBeRemovedThreads)
 58              {
 59                  _ = threads.Remove(t);
 60              }
 61  
 62              if (!found)
 63              {
 64                  threads.Add(thread);
 65              }
 66          }
 67      }
 68  
 69      internal static string DumpThreadsStack()
 70      {
 71          string stack = "\r\nMANAGED THREADS: " + threads.Count.ToString(CultureInfo.InvariantCulture) + "\r\n";
 72          stack += Logger.GetStackTrace(new StackTrace());
 73          return stack;
 74      }
 75  
 76      internal void SetApartmentState(ApartmentState apartmentState)
 77      {
 78          thread.SetApartmentState(apartmentState);
 79      }
 80  
 81      internal void Start()
 82      {
 83          thread.Start();
 84      }
 85  
 86      internal void Start(object parameter)
 87      {
 88          thread.Start(parameter);
 89      }
 90  
 91      internal static void Sleep(int millisecondsTimeout)
 92      {
 93          System.Threading.Thread.Sleep(millisecondsTimeout);
 94      }
 95  
 96      internal static System.Threading.Thread CurrentThread => System.Threading.Thread.CurrentThread;
 97  
 98      internal ThreadPriority Priority
 99      {
100          get => thread.Priority;
101          set => thread.Priority = value;
102      }
103  
104      internal System.Threading.ThreadState ThreadState => thread.ThreadState;
105  }