ThreadImpl.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #pragma once
  2. #if !IL2CPP_THREADS_STD && IL2CPP_THREADS_WIN32 && !RUNTIME_TINY
  3. #include "os/ErrorCodes.h"
  4. #include "os/Thread.h"
  5. #include "os/WaitStatus.h"
  6. #include "utils/NonCopyable.h"
  7. #include "WindowsHeaders.h"
  8. #include "os/Generic/WaitObject.h"
  9. #include "Baselib.h"
  10. #include "Cpp/CappedSemaphore.h"
  11. #include "Cpp/Atomic.h"
  12. #define IL2CPP_DEFAULT_STACK_SIZE ( 1 * 1024 * 1024) // default .NET stacksize is 1mb
  13. namespace il2cpp
  14. {
  15. namespace os
  16. {
  17. class ThreadImpl : public il2cpp::utils::NonCopyable
  18. {
  19. public:
  20. ThreadImpl();
  21. ~ThreadImpl();
  22. size_t Id();
  23. ErrorCode Run(Thread::StartFunc func, void* arg, int64_t affinityMask);
  24. void SetName(const char* name);
  25. void SetPriority(ThreadPriority priority);
  26. ThreadPriority GetPriority();
  27. void SetStackSize(size_t newsize)
  28. {
  29. // only makes sense if it's called BEFORE the thread has been created
  30. IL2CPP_ASSERT(m_ThreadHandle == NULL);
  31. // if newsize is zero we use the per-platform default value for size of stack
  32. if (newsize == 0)
  33. {
  34. newsize = IL2CPP_DEFAULT_STACK_SIZE;
  35. }
  36. m_StackSize = newsize;
  37. }
  38. void CheckForUserAPCAndHandle();
  39. void SetWaitObject(WaitObject* waitObject);
  40. void ReleaseSemaphore() {m_ConditionSemaphore.Release(1);}
  41. void AcquireSemaphore() {m_ConditionSemaphore.Acquire();}
  42. bool TryTimedAcquireSemaphore(uint32_t timeout) { return m_ConditionSemaphore.TryTimedAcquire(baselib::timeout_ms(timeout));}
  43. static int GetMaxStackSize();
  44. void QueueUserAPC(Thread::APCFunc func, void* context);
  45. ApartmentState GetApartment();
  46. ApartmentState GetExplicitApartment();
  47. ApartmentState SetApartment(ApartmentState state);
  48. void SetExplicitApartment(ApartmentState state);
  49. static void Sleep(uint32_t ms, bool interruptible);
  50. static size_t CurrentThreadId();
  51. static ThreadImpl* CreateForCurrentThread();
  52. static ThreadImpl* GetCurrentThread();
  53. static bool YieldInternal();
  54. #if IL2CPP_HAS_NATIVE_THREAD_CLEANUP
  55. static void SetNativeThreadCleanup(Thread::ThreadCleanupFunc cleanupFunction);
  56. static void RegisterCurrentThreadForCleanup(void* arg);
  57. static void UnregisterCurrentThreadForCleanup();
  58. static void OnCurrentThreadExiting();
  59. #endif
  60. baselib::atomic<WaitObject*> m_CurrentWaitObject;
  61. struct APCRequest
  62. {
  63. Thread::APCFunc callback;
  64. void* context;
  65. APCRequest(Thread::APCFunc callback, void* context) :
  66. callback(callback), context(context)
  67. {
  68. }
  69. };
  70. baselib::Lock m_PendingAPCsMutex;
  71. std::vector<APCRequest> m_PendingAPCs;
  72. baselib::CappedSemaphore m_ConditionSemaphore;
  73. private:
  74. HANDLE m_ThreadHandle;
  75. volatile DWORD m_ThreadId;
  76. SIZE_T m_StackSize;
  77. ApartmentState m_ApartmentState;
  78. ThreadPriority m_Priority;
  79. void SetNameForDebugger(const char* name);
  80. };
  81. }
  82. }
  83. #endif