#pragma once #include "os/ErrorCodes.h" #include "os/Handle.h" #include "os/WaitStatus.h" #include "utils/NonCopyable.h" #include "Baselib.h" #include "Cpp/ReentrantLock.h" namespace il2cpp { namespace os { class MutexImpl; class FastMutexImpl; class Mutex : public il2cpp::utils::NonCopyable { public: Mutex(bool initiallyOwned = false); ~Mutex(); void Lock(bool interruptible = false); bool TryLock(uint32_t milliseconds = 0, bool interruptible = false); void Unlock(); void* GetOSHandle(); private: MutexImpl* m_Mutex; }; struct AutoLock : public il2cpp::utils::NonCopyable { AutoLock(Mutex* mutex) : m_Mutex(mutex) { m_Mutex->Lock(); } ~AutoLock() { m_Mutex->Unlock(); } private: Mutex* m_Mutex; }; class MutexHandle : public Handle { public: MutexHandle(Mutex* mutex) : m_Mutex(mutex) {} virtual ~MutexHandle() { delete m_Mutex; } virtual bool Wait() { m_Mutex->Lock(true); return true; } virtual bool Wait(uint32_t ms) { return m_Mutex->TryLock(ms, true); } virtual WaitStatus Wait(bool interruptible) { m_Mutex->Lock(interruptible); return kWaitStatusSuccess; } virtual WaitStatus Wait(uint32_t ms, bool interruptible) { return m_Mutex->TryLock(ms, interruptible) ? kWaitStatusSuccess : kWaitStatusFailure; } virtual void Signal() { m_Mutex->Unlock(); } virtual void* GetOSHandle() { return m_Mutex->GetOSHandle(); } Mutex* Get() { return m_Mutex; } private: Mutex* m_Mutex; }; /// Lightweight mutex that has no support for interruption or timed waits. Meant for /// internal use only. class FastMutex { public: FastMutex(); ~FastMutex(); void Lock(); void Unlock(); FastMutexImpl* GetImpl(); private: FastMutexImpl* m_Impl; }; struct FastAutoLock : public il2cpp::utils::NonCopyable { FastAutoLock(baselib::ReentrantLock* mutex) : m_Mutex(mutex) { m_Mutex->Acquire(); } ~FastAutoLock() { m_Mutex->Release(); } #if IL2CPP_DEBUG bool IsLock(baselib::ReentrantLock* mutex) const { return mutex == m_Mutex; } #endif private: baselib::ReentrantLock* m_Mutex; }; struct FastAutoUnlock : public il2cpp::utils::NonCopyable { FastAutoUnlock(baselib::ReentrantLock* mutex) : m_Mutex(mutex) { m_Mutex->Release(); } ~FastAutoUnlock() { m_Mutex->Acquire(); } private: baselib::ReentrantLock* m_Mutex; }; } }