/usr/include/tse3/Mutex.h is in libtse3-dev 0.3.1-4.3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | /*
* @(#)Mutex.h 3.00 2 October 2000
*
* Copyright (c) 2000 Pete Goodliffe (pete@cthree.org)
*
* This file is part of TSE3 - the Trax Sequencer Engine version 3.00.
*
* This library is modifiable/redistributable under the terms of the GNU
* General Public License.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING. If not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef TSE3_MUTEX_H
#define TSE3_MUTEX_H
namespace TSE3
{
namespace Impl
{
/**
* This class provides an abtract interface for a mutex implementation.
*
* The @ref NullMutexImpl class inherits from this base class, and
* provides a 'null' implementation: performing no lock or unlock
* operations.
*
* This class provides a way of specifying mutex behaviour in a
* platform independant manner.
*
* If you want to use TSE3 in a thread-safe manner then you will
* need to implement a MutexImpl class and pass it to the @ref Mutex
* class.
*
* A MutexImpl is created in an unlocked state.
*
* @short Mutex implementation base class
* @author Pete Goodliffe
* @version 3.00
* @see Mutex
*/
class MutexImpl
{
public:
virtual ~MutexImpl() {}
/**
* Locks the mutex.
*
* If the mutex implementation is already locked by a different
* thread, then this thread will block until the previous one
* unlocks the mutex.
*
* A single thread can lock the mutex multiple times. However,
* subsequent calls to lock have no effect. There must be the
* same number of calls to @ref unlock before the MutexImpl
* is unlocked, though.
*
* @see unlock
*/
virtual void lock() = 0;
/**
* Unlocks the mutex. To unlock the mutex fully, as many
* unlocks must be called as locks.
*
* If the MutexImpl is already unlocked, then nothing
* will happen.
*
* @see lock
*/
virtual void unlock() = 0;
/**
* Returns true if the MutexImpl is locked, false otherwise.
*
* @see lock
* @see unlock
*/
virtual bool locked() = 0;
};
/**
* A default, 'null' implementation of the @ref MutexImpl class that
* is used by thread-unsafe versions of the TSE3 library.
*
* The @ref lock and @ref unlock methods are essentially no-ops - they
* don't perform any locking whatsoever.
*
* @short 'Null' @ref MutexImpl class
* @author Pete Goodliffe
* @version 3.00
* @see MutexImpl
*/
class NullMutexImpl : public MutexImpl
{
public:
NullMutexImpl() : _locked(0) {}
virtual ~NullMutexImpl() {}
/**
* @reimplemented
*/
virtual void lock() { ++_locked; }
/**
* @reimplemented
*/
virtual void unlock() { if (_locked) --_locked; }
/**
* @reimplemented
*/
virtual bool locked() { return _locked; }
private:
int _locked;
};
/**
* The Mutex class is used by TSE3 to ensure thread safety. All
* potentially contenious TSE3 methods claim a Mutex to prevent TSE3
* being entered by multiple threads.
*
* This Mutex class provides a platform independant interface
* to the underlying mutex implementation (which is accessed through
* the @ref MutexImpl class interface).
*
* There is a single, global TSE3 Mutex object that is used by the
* entire library. This is accessed by calling the @ref mutex
* static member function.
*
* On each different platform supported by TSE3 there will be a
* specific @ref MutexImpl class.
*
* By default, the TSE3 library is not configured to be thread safe:
* the default @ref MutexImpl that will be used is the
* @ref NullMutexImpl. This implementation performs no operations
* for lock and unlock.
*
* In order to make TSE3 thread safe, you must have an implementation
* of the @ref MutexImpl class, and pass this to the static
* @ref setImpl method <b>BEFORE</b> using any of the other TSE3 API.
* (In fact, you only need set this before the first call to the
* static @ref mutex method, but most API functions will call this
* at some time).
*
* A simplification of the Mutex API is provided by the
* @ref CritSec class. In some cases this is a more
* convenient interface to use.
*
* @short Mutex class used to ensure TSE3 thread safety
* @author Pete Goodliffe
* @version 3.00
* @see MutexImpl
* @see NullMutexImpl
* @see CritSec
*/
class Mutex
{
public:
/**
* Creates a Mutex object with the specified implementation.
*
* This @ref MutexImpl object is considered to be owned by
* the Mutex class, and will be deleted when the Mutex is
* deleted - you need not delete it yourself.
*
* This does imply that there must be a one-to-one relationship
* between Mutex objects and @ref MutexImpl objects.
*
* A Mutex is created in an unlocked state.
*
* @param impl @ref MutexImpl object to use
*/
Mutex(MutexImpl *i) : impl(i) {}
~Mutex();
/**
* Sets the @ref MutexImpl class that will be used by the
* global Mutex object.
*
* It is very important to call this method BEFORE
* calling @ref mutex to use the global Mutex object. Since
* most TSE3 API methods call mutex, it is safest to set
* the @ref MutexImpl before calling any other TSE3 method.
*
* The impl you specify must exist for as long as you use
* the TSE3 library.
*
* If you do not specify a @ref MutexImpl then a default
* @ref NullMutexImpl will be used, and TSE3 will not
* be thread-safe.
*
* You may only call this once: subsequent calls are ignored
* and the first @ref MutexImpl specified is used.
*
* @param impl @ref MutexImpl to use. This will be deleted
* by the Mutex class - you may forget about it.
*/
static void setImpl(MutexImpl *impl);
/**
* Provides access to the global Mutex object used to lock
* the TSE3 library.
*
* The first time this method is called, a Mutex object will
* be created with the @ref MutexImpl specified by
* @ref setImpl.
*/
static Mutex *mutex();
/**
* Locks the Mutex.
*
* If the Mutex is already locked by a different
* thread, then this thread will block until the previous one
* unlocks the mutex.
*
* A single thread can lock the mutex multiple times. However,
* subsequent calls to lock have no effect. There must be the
* same number of calls to @ref unlock before the Mutex
* is unlocked, though.
*
* @see unlock
*/
void lock()
{
#ifndef TSE3_WITHOUT_MUTEX
impl->lock();
#endif
}
/**
* Unlocks the Mutex. To unlock the mutex fully, as many
* unlocks must be called as locks.
*
* If the Mutex is already unlocked, then nothing will happen.
*
* @see lock
*/
void unlock()
{
#ifndef TSE3_WITHOUT_MUTEX
impl->unlock();
#endif
}
private:
MutexImpl *impl;
static MutexImpl *globalImpl;
};
/**
* A 'critical section' class that provides a somewhat more convenient
* interface to the @ref Mutex class. A CritSec object simply locks
* the global @ref Mutex upon creation and unlocks it on destruction.
*
* Therefore, this means that rather than write:
* <pre>
* {
* TSE3::Impl::Mutex::mutex()->lock();
* // do something
* TSE3::Impl::Mutex::mutex()->unlock();
* }
* </pre>
*
* You can simply write:
* <pre>
* {
* TSE3::Impl::CritSec cs;
* // do something
* }
* </pre>
*
* Clearly, this prevents a possible source of error, where you might
* forget to unlock the mutex after having locked it. It is also in
* most cases a lot more convenient to use.
*
* The CritSec class is small, simple and implemented with inline
* functions so the resultant generated code for both of the above
* examples is identical.
*
* @short Convenient API for @ref Mutex class
* @author Pete Goodliffe
* @version 3.00
* @see Mutex
*/
class CritSec
{
public:
CritSec()
{
#ifndef TSE3_WITHOUT_MUTEX
Mutex::mutex()->lock();
#endif
}
~CritSec()
{
#ifndef TSE3_WITHOUT_MUTEX
Mutex::mutex()->unlock();
#endif
}
};
}
}
#endif
|