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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/********************************************************************************
* *
* 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/> *
********************************************************************************/
#ifndef FXMUTEX_H
#define FXMUTEX_H
namespace FX {
/**
* FXMutex provides a mutex which can be used to enforce critical
* sections around updates of data shared by multiple threads.
*/
class FXAPI FXMutex {
friend class FXCondition;
private:
FXuval data[24];
private:
FXMutex(const FXMutex&);
FXMutex &operator=(const FXMutex&);
public:
/**
* Initialize the mutex; if the parameter recursive is true,
* the mutex is reentrant, i.e. counts the number of locks and unlocks.
*/
FXMutex(FXbool recursive=false);
/// Lock the mutex
void lock();
/// Return true if succeeded locking the mutex
FXbool trylock();
/// Return true if mutex is already locked
FXbool locked();
/// Unlock mutex
void unlock();
/// Delete the mutex
~FXMutex();
};
/**
* Establish a correspondence between a C++ scope and a FXMutex,
* so that entering and leaving the scope in which the scoped lock
* is defined will automatically lock and unlock the associated
* mutex.
* This will typically result in much less coding, and in addition
* will make the code safe from exceptions.
*/
class FXAPI FXScopedMutex {
private:
FXMutex& mtx;
private:
FXScopedMutex();
FXScopedMutex(const FXScopedMutex&);
FXScopedMutex& operator=(const FXScopedMutex&);
public:
/// Construct and lock associated mutex
FXScopedMutex(FXMutex& m):mtx(m){ lock(); }
/// Return reference to associated mutex
FXMutex& mutex(){ return mtx; }
/// Lock mutex
void lock(){ mtx.lock(); }
/// Return true if succeeded locking the mutex
FXbool trylock(){ return mtx.trylock(); }
/// Return true if mutex is already locked
FXbool locked(){ return mtx.locked(); }
/// Unlock mutex
void unlock(){ mtx.unlock(); }
/// Destroy and unlock associated mutex
~FXScopedMutex(){ unlock(); }
};
/**
* The Reverse Mutex unlocks its associated FXMutex when entering the
* scope, and automatically relocks it upon exiting the scope.
* Exceptions raised while in this region will automatically relock
* the mutex upon leaving the enclosing scope.
*/
class FXAPI FXReverseMutex {
private:
FXMutex& mtx;
private:
FXReverseMutex();
FXReverseMutex(const FXReverseMutex&);
FXReverseMutex& operator=(const FXReverseMutex&);
public:
/// Construct and unlock associated mutex
FXReverseMutex(FXMutex& m):mtx(m){ unlock(); }
/// Return reference to associated mutex
FXMutex& mutex(){ return mtx; }
/// Lock mutex
void lock(){ mtx.lock(); }
/// Return true if succeeded locking the mutex
FXbool trylock(){ return mtx.trylock(); }
/// Return true if mutex is already locked
FXbool locked(){ return mtx.locked(); }
/// Unlock mutex
void unlock(){ mtx.unlock(); }
/// Destroy and relock associated mutex
~FXReverseMutex(){ lock(); }
};
}
#endif
|