mirror of
https://github.com/therealKyp/Earth-and-Beyond-server
synced 2026-08-13 22:23:03 -04:00
93 lines
1.8 KiB
C++
93 lines
1.8 KiB
C++
// Mutex.cpp
|
|
//
|
|
// Encapsulates mutual exclusion methods for both Windows and Linux platforms.
|
|
//
|
|
// DESIGN NOTES:
|
|
// Windows allows nested calls to the mutex lock method, but Linux does not.
|
|
// This class has been modified to add a "Lock Count" to pthreads_mutex in order
|
|
// to support nested calls.
|
|
|
|
// In practice a mutex is a semaphore with count 1
|
|
|
|
#include "Net7.h"
|
|
#include "Mutex.h"
|
|
|
|
Mutex::Mutex()
|
|
{
|
|
#ifdef WIN32
|
|
InitializeCriticalSection(&m_Mutex);
|
|
#else
|
|
pthread_mutex_init(&m_Mutex, NULL);
|
|
m_LockCount = 0;
|
|
#endif
|
|
}
|
|
|
|
Mutex::~Mutex()
|
|
{
|
|
#ifdef WIN32
|
|
DeleteCriticalSection(&m_Mutex);
|
|
#else
|
|
pthread_mutex_destroy(&m_Mutex);
|
|
#endif
|
|
}
|
|
|
|
void Mutex::Lock()
|
|
{
|
|
#ifdef WIN32
|
|
|
|
bool locked = false;
|
|
if (m_Mutex.LockCount > 0)
|
|
{
|
|
fprintf(stderr,"Mutex appears locked %d.", m_Mutex.LockCount);
|
|
locked = true;
|
|
}
|
|
EnterCriticalSection(&m_Mutex);
|
|
|
|
if (locked)
|
|
{
|
|
fprintf(stderr,"Mutex unlocked, and re-blocked [%d].\n", m_Mutex.LockCount);
|
|
}
|
|
#else
|
|
|
|
pthread_t thread_id = pthread_self();
|
|
int ret = pthread_mutex_trylock(&m_Mutex);
|
|
if (ret == 0)
|
|
{
|
|
// Lock was successful
|
|
m_ThreadID = thread_id;
|
|
m_LockCount++;
|
|
}
|
|
else if (m_ThreadID == thread_id)
|
|
{
|
|
// Lock failed, we already own the lock
|
|
m_LockCount++;
|
|
}
|
|
else
|
|
{
|
|
// Another thread owns the lock.
|
|
// We have no choice but to wait until they release it.
|
|
pthread_mutex_lock(&m_Mutex);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void Mutex::Unlock()
|
|
{
|
|
#ifdef WIN32
|
|
LeaveCriticalSection(&m_Mutex);
|
|
|
|
#else
|
|
if (m_LockCount > 0)
|
|
{
|
|
m_LockCount--;
|
|
if (m_LockCount == 0)
|
|
{
|
|
// When the lock count reaches zero, release the resource
|
|
pthread_mutex_unlock(&m_Mutex);
|
|
}
|
|
}
|
|
// else mutex is not locked, ignore the call
|
|
#endif
|
|
}
|
|
|