/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef _THREADING_MUTEX_H #define _THREADING_MUTEX_H class SERVER_DECL Mutex { public: friend class Condition; /** Initializes a mutex class, with InitializeCriticalSection / pthread_mutex_init */ Mutex(); /** Deletes the associated critical section / mutex */ ~Mutex(); /** Acquires this mutex. If it cannot be acquired immediately, it will block. */ inline void Acquire() { #ifndef WIN32 pthread_mutex_lock(&mutex); #else EnterCriticalSection(&cs); #endif } /** Releases this mutex. No error checking performed */ inline void Release() { #ifndef 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() { #ifndef WIN32 return (pthread_mutex_trylock(&mutex) == 0); #else return TryEnterCriticalSection(&cs); #endif } protected: #ifdef 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 }; #ifdef WIN32 class SERVER_DECL 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 == 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 == 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 Mutex #endif #endif