1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/********************************************************************************
* *
* M u t e x C l a s s *
* *
*********************************************************************************
* Copyright (C) 2004,2022 by Jeroen van der Zijp. All Rights Reserved. *
*********************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This library 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/> *
********************************************************************************/
#include "xincs.h"
#include "fxver.h"
#include "fxdefs.h"
#include "FXMutex.h"
/*
Notes:
- Simple (optionally recursive) mutex variable.
- An amorphous blob of memory is reserved in the declaration, without revealing
implementation details. This is better than allocating memory dynamically, both
in terms of speed as well as the possibility that hitting malloc() will involve
another mutex.
- Hopefully it is big enough for all supported platforms. But just in case, there's
an assert in the constructor to verify that enough space is reserved for the
implementation.
- I do therefore recommend running this in debug mode first time around on a
new platform.
- If you run into this, try to figure out sizeof(pthread_mutex_t) and
let me know about it (jeroen@fox-toolkit.net).
*/
using namespace FX;
/*******************************************************************************/
namespace FX {
// Initialize mutex
FXMutex::FXMutex(FXbool recursive){
#if defined(WIN32)
// If this fails on your machine, determine what value
// of sizeof(CRITICAL_SECTION) is supposed to be on your
// machine and mail it to: jeroen@fox-toolkit.net!!
//FXTRACE((150,"sizeof(CRITICAL_SECTION)=%d\n",sizeof(CRITICAL_SECTION)));
FXASSERT_STATIC(sizeof(data)>=sizeof(CRITICAL_SECTION));
InitializeCriticalSection((CRITICAL_SECTION*)data);
#else
// If this fails on your machine, determine what value
// of sizeof(pthread_mutex_t) is supposed to be on your
// machine and mail it to: jeroen@fox-toolkit.net!!
//FXTRACE((150,"sizeof(pthread_mutex_t)=%d\n",sizeof(pthread_mutex_t)));
FXASSERT_STATIC(sizeof(data)>=sizeof(pthread_mutex_t));
pthread_mutexattr_t mutexatt;
pthread_mutexattr_init(&mutexatt);
pthread_mutexattr_settype(&mutexatt,recursive?PTHREAD_MUTEX_RECURSIVE:PTHREAD_MUTEX_DEFAULT);
pthread_mutex_init((pthread_mutex_t*)data,&mutexatt);
pthread_mutexattr_destroy(&mutexatt);
#endif
}
// Lock the mutex
void FXMutex::lock(){
#if defined(WIN32)
EnterCriticalSection((CRITICAL_SECTION*)data);
#else
pthread_mutex_lock((pthread_mutex_t*)data);
#endif
}
// Try lock the mutex
FXbool FXMutex::trylock(){
#if defined(WIN32)
return TryEnterCriticalSection((CRITICAL_SECTION*)data)!=0;
#elif defined(WIN32)
return false;
#else
return pthread_mutex_trylock((pthread_mutex_t*)data)==0;
#endif
}
// Unlock mutex
void FXMutex::unlock(){
#if defined(WIN32)
LeaveCriticalSection((CRITICAL_SECTION*)data);
#else
pthread_mutex_unlock((pthread_mutex_t*)data);
#endif
}
// Test if locked
FXbool FXMutex::locked(){
if(trylock()){
unlock();
return false;
}
return true;
}
// Delete mutex
FXMutex::~FXMutex(){
#if defined(WIN32)
DeleteCriticalSection((CRITICAL_SECTION*)data);
#else
pthread_mutex_destroy((pthread_mutex_t*)data);
#endif
}
}
|