WaitObject.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. #if (IL2CPP_THREADS_PTHREAD || IL2CPP_THREADS_WIN32) && !RUNTIME_TINY
  3. #include <stdint.h>
  4. #include <limits.h>
  5. #include "utils/NonCopyable.h"
  6. #include "os/WaitStatus.h"
  7. #include "Baselib.h"
  8. #include "Cpp/Lock.h"
  9. #include "utils/dynamic_array.h"
  10. #if IL2CPP_THREADS_WIN32
  11. //#include "os/Win32/ThreadImpl.h"
  12. #else
  13. //#include "os/Posix/ThreadImpl.h"
  14. #endif
  15. namespace il2cpp
  16. {
  17. namespace os
  18. {
  19. class ThreadImpl;
  20. ////TODO: generalize this so that it can be used with c++11 condition variables
  21. class WaitObject : public il2cpp::utils::NonCopyable
  22. {
  23. public:
  24. const uint32_t kNoTimeout = UINT_MAX;
  25. class ReleaseOnDestroy
  26. {
  27. public:
  28. FORCE_INLINE ReleaseOnDestroy(baselib::Lock& lockReference) : m_LockReference(lockReference) {m_LockReference.Acquire();}
  29. FORCE_INLINE ~ReleaseOnDestroy() { m_LockReference.Release(); }
  30. private:
  31. baselib::Lock& m_LockReference;
  32. };
  33. ~WaitObject();
  34. WaitStatus Wait(bool interruptible = false);
  35. WaitStatus Wait(uint32_t ms, bool interruptible = false);
  36. void* GetOSHandle();
  37. static void LockWaitObjectDeletion();
  38. static void UnlockWaitObjectDeletion();
  39. protected:
  40. enum Type
  41. {
  42. kMutex, /// All mutexes are recursive.
  43. kManualResetEvent,
  44. kAutoResetEvent,
  45. kSemaphore
  46. };
  47. struct SThreadPairPosix
  48. {
  49. SThreadPairPosix(ThreadImpl* _thread, WaitObject* _owner)
  50. {
  51. thread = _thread;
  52. owner = _owner;
  53. }
  54. ThreadImpl* thread;
  55. WaitObject* owner;
  56. };
  57. WaitObject(Type type);
  58. Type m_Type;
  59. /// Always have to acquire this mutex to touch m_Count.
  60. baselib::Lock m_Mutex;
  61. /// Array of threads waiting for this sync primitive
  62. il2cpp::utils::dynamic_array<SThreadPairPosix> m_WaitingThreads;
  63. /// "Release" count for the primitive. Means different things depending on the type of primitive
  64. /// but for all primitives, we wait until this is zero. Semaphores are the only primitive for which
  65. /// this can go past 1.
  66. uint32_t m_Count;
  67. /// Number of threads waiting on this object. This is used to prevent unnecessary signals
  68. /// on m_Condition.
  69. uint32_t m_WaitingThreadCount;
  70. bool HaveWaitingThreads() const { return (m_WaitingThreadCount != 0); }
  71. void WakeupOneThread() { WakeupThreads(true); }
  72. void WakeupAllThreads() { WakeupThreads(false); }
  73. void WakeupThreads(bool wakeupOneThread);
  74. void ConditionWait(ThreadImpl* thread);
  75. bool ConditionTimedWait(ThreadImpl* thread, uint32_t timeout);
  76. void PushThreadToWaitersList(WaitObject* owner, ThreadImpl* thread);
  77. void PopThreadFromWaitersList(ThreadImpl* thread);
  78. };
  79. }
  80. }
  81. #endif // (IL2CPP_THREADS_PTHREAD || IL2CPP_THREADS_WIN32) && !RUNTIME_TINY