mxoemu/Reality/Source/Threading/NativeMutex.h
rajkosto 3de69bc911 Damn it TW you broke half of the multi-user stuff...had to fix it all back.
Also modified Sockets library not to deconstruct margin client objects on MXO's half-closed connection after session establishment.
2010-08-11 15:23:10 +02:00

163 lines
3.6 KiB
C++

// ***************************************************************************
//
// Reality - The Matrix Online Server Emulator
// Copyright (C) 2006-2010 Rajko Stojadinovic
// http://mxoemu.info
//
// ---------------------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ---------------------------------------------------------------------------
//
// ***************************************************************************
#ifndef MXOSIM_MUTEX_H
#define MXOSIM_MUTEX_H
#include "../Common.h"
class NativeMutex
{
public:
friend class Condition;
/** Initializes a mutex class, with InitializeCriticalSection / pthread_mutex_init
*/
NativeMutex();
/** Deletes the associated critical section / mutex
*/
~NativeMutex();
/** Acquires this mutex. If it cannot be acquired immediately, it will block.
*/
inline void Acquire()
{
#if PLATFORM != PLATFORM_WIN32
pthread_mutex_lock(&mutex);
#else
EnterCriticalSection(&cs);
#endif
}
/** Releases this mutex. No error checking performed
*/
inline void Release()
{
#if PLATFORM != PLATFORM_WIN32
pthread_mutex_unlock(&mutex);
#else
LeaveCriticalSection(&cs);
#endif
}
/** Attempts to acquire this mutex. If it cannot be acquired (held by another thread)
* it will return false.
* @return false if cannot be acquired, true if it was acquired.
*/
inline bool AttemptAcquire()
{
#if PLATFORM != PLATFORM_WIN32
return (pthread_mutex_trylock(&mutex) == 0);
#else
return (TryEnterCriticalSection(&cs) == TRUE ? true : false);
#endif
}
protected:
#if PLATFORM == PLATFORM_WIN32
/** Critical section used for system calls
*/
CRITICAL_SECTION cs;
#else
/** Static mutex attribute
*/
static bool attr_initalized;
static pthread_mutexattr_t attr;
/** pthread struct used in system calls
*/
pthread_mutex_t mutex;
#endif
};
#if PLATFORM == PLATFORM_WIN32
class FastMutex
{
#pragma pack(push,8)
volatile long m_lock;
#pragma pack(pop)
DWORD m_recursiveCount;
public:
inline FastMutex() : m_lock(0),m_recursiveCount(0) {}
inline ~FastMutex() {}
inline void Acquire()
{
DWORD thread_id = GetCurrentThreadId(), owner;
if(thread_id == (DWORD)m_lock)
{
++m_recursiveCount;
return;
}
for(;;)
{
owner = InterlockedCompareExchange(&m_lock, thread_id, 0);
if(owner == 0)
break;
Sleep(0);
}
++m_recursiveCount;
}
inline bool AttemptAcquire()
{
DWORD thread_id = GetCurrentThreadId();
if(thread_id == (DWORD)m_lock)
{
++m_recursiveCount;
return true;
}
DWORD owner = InterlockedCompareExchange(&m_lock, thread_id, 0);
if(owner == 0)
{
++m_recursiveCount;
return true;
}
return false;
}
inline void Release()
{
if((--m_recursiveCount) == 0)
InterlockedExchange(&m_lock, 0);
}
};
#else
#define FastMutex NativeMutex
#endif
#endif /* MXOSIM_MUTEX_H */