net7/branches/linux-port/Mutex.cpp
2014-05-11 16:54:16 -04:00

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
}