Files
RedHotRoast-ios/HybridCLRData/LocalIl2CppData-OSXEditor/il2cpp/libil2cpp/os/Generic/MutexImpl.h
T
2026-07-17 14:03:00 +08:00

93 lines
2.4 KiB
C++

#pragma once
#if (IL2CPP_THREADS_PTHREAD || IL2CPP_THREADS_WIN32) && !RUNTIME_TINY
#include "os/ErrorCodes.h"
#include "os/WaitStatus.h"
#include "os/Generic/WaitObject.h"
#include "Baselib.h"
#include "Cpp/ReentrantLock.h"
#include "os/Thread.h"
namespace il2cpp
{
namespace os
{
class Thread;
class MutexImpl : public WaitObject
{
public:
MutexImpl()
: WaitObject(kMutex)
, m_OwningThread(NULL)
, m_RecursionCount(0)
{
// For a mutex, 1 means unlocked.
m_Count = 1;
}
void Lock(bool interruptible)
{
TryLock(kNoTimeout, interruptible);
}
bool TryLock(uint32_t milliseconds, bool interruptible)
{
Thread* currentThread = Thread::GetCurrentThread();
if (m_OwningThread == currentThread)
{
IL2CPP_ASSERT(m_Count == 0);
++m_RecursionCount;
return true;
}
if (Wait(milliseconds, interruptible) == kWaitStatusSuccess)
{
m_OwningThread = currentThread;
m_RecursionCount = 1;
return true;
}
return false;
}
void Unlock()
{
IL2CPP_ASSERT(m_OwningThread == Thread::GetCurrentThread());
// Undo one locking level.
--m_RecursionCount;
if (m_RecursionCount > 0)
{
// Still locked.
return;
}
// Ok, we're releasing the mutex. Lock and signal. We don't absolutely
// need the lock as we are already owning the mutex here but play it safe.
WaitObject::ReleaseOnDestroy lock(m_Mutex);
IL2CPP_ASSERT(m_Count == 0);
m_Count = 1; // Unintuitive but 1 means unlocked.
m_OwningThread = NULL;
// Signal condition so that either a thread that's already waiting or a thread that
// comes around later and waits can claim the mutex.
if (HaveWaitingThreads())
WakeupOneThread();
}
private:
/// Thread that currently owns the object. Used for recursion checks.
Thread* m_OwningThread;
/// Number of recursive locks on the owning thread.
uint32_t m_RecursionCount;
};
}
}
#endif