MutexImpl.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #pragma once
  2. #if (IL2CPP_THREADS_PTHREAD || IL2CPP_THREADS_WIN32) && !RUNTIME_TINY
  3. #include "os/ErrorCodes.h"
  4. #include "os/WaitStatus.h"
  5. #include "os/Generic/WaitObject.h"
  6. #include "Baselib.h"
  7. #include "Cpp/ReentrantLock.h"
  8. #include "os/Thread.h"
  9. namespace il2cpp
  10. {
  11. namespace os
  12. {
  13. class Thread;
  14. class MutexImpl : public WaitObject
  15. {
  16. public:
  17. MutexImpl()
  18. : WaitObject(kMutex)
  19. , m_OwningThread(NULL)
  20. , m_RecursionCount(0)
  21. {
  22. // For a mutex, 1 means unlocked.
  23. m_Count = 1;
  24. }
  25. void Lock(bool interruptible)
  26. {
  27. TryLock(kNoTimeout, interruptible);
  28. }
  29. bool TryLock(uint32_t milliseconds, bool interruptible)
  30. {
  31. Thread* currentThread = Thread::GetCurrentThread();
  32. if (m_OwningThread == currentThread)
  33. {
  34. IL2CPP_ASSERT(m_Count == 0);
  35. ++m_RecursionCount;
  36. return true;
  37. }
  38. if (Wait(milliseconds, interruptible) == kWaitStatusSuccess)
  39. {
  40. m_OwningThread = currentThread;
  41. m_RecursionCount = 1;
  42. return true;
  43. }
  44. return false;
  45. }
  46. void Unlock()
  47. {
  48. IL2CPP_ASSERT(m_OwningThread == Thread::GetCurrentThread());
  49. // Undo one locking level.
  50. --m_RecursionCount;
  51. if (m_RecursionCount > 0)
  52. {
  53. // Still locked.
  54. return;
  55. }
  56. // Ok, we're releasing the mutex. Lock and signal. We don't absolutely
  57. // need the lock as we are already owning the mutex here but play it safe.
  58. WaitObject::ReleaseOnDestroy lock(m_Mutex);
  59. IL2CPP_ASSERT(m_Count == 0);
  60. m_Count = 1; // Unintuitive but 1 means unlocked.
  61. m_OwningThread = NULL;
  62. // Signal condition so that either a thread that's already waiting or a thread that
  63. // comes around later and waits can claim the mutex.
  64. if (HaveWaitingThreads())
  65. WakeupOneThread();
  66. }
  67. private:
  68. /// Thread that currently owns the object. Used for recursion checks.
  69. Thread* m_OwningThread;
  70. /// Number of recursive locks on the owning thread.
  71. uint32_t m_RecursionCount;
  72. };
  73. }
  74. }
  75. #endif