casacore
Mutex.h
Go to the documentation of this file.
1 //# Mutex.h: Classes to handle mutexes and (un)locking
2 //# Copyright (C) 2011
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef CASA_MUTEX_H
29 #define CASA_MUTEX_H
30 
31 #include <casacore/casa/aips.h>
32 
33 //# Mostly copied from the LOFAR software.
34 
35 namespace casacore {
36 
37  // <summary>Wrapper around a pthreads mutex</summary>
38  // <use visibility=export>
39  //
40  // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
41  // </reviewed>
42  //
43  // <synopsis>
44  // This class is a wrapper around a phtreads mutex.
45  // <br>Although the Mutex class has a lock function, class ScopedMutexLock
46  // should be used to obtain a lock, because it makes locking exception-safe.
47  // </synopsis>
48 
49  class Mutex
50  {
51  public:
52  // Define the type of mutex.
53  // (see phtread_mutexattr_settype for their meaning).
54  // In Debug mode, type Auto will use PTHREAD_MUTEX_ERRORCHECK,
55  // otherwise PTHREAD_MUTEX_DEFAULT.
57 
58  // Create the mutex.
59  Mutex (Type type=Auto);
60 
61  // Destroy the mutex.
62  ~Mutex();
63 
64  // Set a lock on the mutex. It waits till it gets the lock.
65  void lock();
66 
67  // Unlock the mutex.
68  void unlock();
69 
70  // Try to lock the mutex. True is returned if it succeeded.
71  bool trylock();
72 
73  private:
74  // Forbid copy constructor.
75  Mutex (const Mutex&);
76  // Forbid assignment.
77  Mutex& operator= (const Mutex&);
78 
79  //# Data members
80  //# Use void*, because we cannot forward declare pthread_mutex_t.
81  void* itsMutex;
82  };
83 
84 
85  // <summary>Exception-safe lock/unlock of a mutex</summary>
86  // <use visibility=export>
87  //
88  // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
89  // </reviewed>
90  //
91  // <synopsis>
92  // The constructor of this class locks a mutex, while the destructor
93  // unlocks it. In this way the user does not need to take care of
94  // unlocking a mutex and is mutex locking fully exception-safe
95  // </synopsis>
96 
98  {
99  public:
100  // Create a lock on the mutex.
102  : itsMutexRef(mutex)
103  { itsMutexRef.lock(); }
104 
105  // The destructor automatically unlocks the mutex.
107  { itsMutexRef.unlock(); }
108 
109  private:
110  // Forbid copy constructor.
112  // Forbid assignment.
114 
116  };
117 
118 
119  // <summary>Thread-safe initialization of global variables</summary>
120  // <use visibility=export>
121  //
122  // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
123  // </reviewed>
124  //
125  // <synopsis>
126  // This class does a double checked lock.
127  // <br>
128  // Often data needs to be initialized once and accessed many times. To do
129  // this in a thread-safe way, a mutex lock needs to be used. However, that
130  // is relatively expensive.
131  // The double checked lock idiom overcomes this problem. A Bool flag tells
132  // if an operation needs to be done. If so, a lock is set and the flag is
133  // tested again in case another thread happened to do the operation between
134  // the test and acquiring the lock.
135  // At the end of the operation the flag is cleared.
136  //
137  //
138  // The flag needs to be declared volatile to avoid execution ordering
139  // problems in case a compiler optimizes too much.
140  // <note role-warning>
141  // This idiom is not fully portable, because on more exotic machines the
142  // caches in different cores may not be synchronized well.
143  // </note>
144  // </synopsis>
145  //
146  // <example>
147  // <srcblock>
148  // // Declare static variables.
149  // static volatile Bool needInit = True;
150  // static Mutex mutex;
151  // // Execute the code in a scope, so the destructor is called automatically.
152  // {
153  // CheckedMutexLock locker(mutex, needInit);
154  // if (locker.doIt()) {
155  // .. do the initialization
156  // }
157  // }
158  // </srcblock>
159  // </example>
160 
162  {
163  public:
164  // Define the initialization function to call.
165  typedef void InitFunc (void*);
166 
167  // Create the mutex and set that the initialization should be done.
168  MutexedInit (InitFunc* func, void* arg=0, Mutex::Type type=Mutex::Auto);
169 
170  // Execute the initialization function if not done yet.
171  void exec()
172  { if (itsDoExec) doExec(); }
173 
174  // Get the mutex (to make it possible to lock for other purposes).
176  { return itsMutex; }
177 
178  private:
179  // Forbid copy constructor.
180  MutexedInit (const MutexedInit&);
181  // Forbid assignment.
183 
184  // Thread-safe execution of the initialization function (if still needed).
185  void doExec();
186 
187  //# Data members
189  InitFunc* itsFunc;
190  void* itsArg;
191  volatile Bool itsDoExec;
192  };
193 
194 
195 } // namespace casacore
196 
197 #endif
void InitFunc(void *)
Define the initialization function to call.
Definition: Mutex.h:165
LatticeExprNode arg(const LatticeExprNode &expr)
volatile Bool itsDoExec
Definition: Mutex.h:191
void unlock()
Unlock the mutex.
Type
Define the type of mutex.
Definition: Mutex.h:56
~Mutex()
Destroy the mutex.
~ScopedMutexLock()
The destructor automatically unlocks the mutex.
Definition: Mutex.h:106
void lock()
Set a lock on the mutex.
Thread-safe initialization of global variables.
Definition: Mutex.h:161
ScopedMutexLock(Mutex &mutex)
Create a lock on the mutex.
Definition: Mutex.h:101
InitFunc * itsFunc
Definition: Mutex.h:189
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
void * itsMutex
Definition: Mutex.h:81
Mutex & operator=(const Mutex &)
Forbid assignment.
bool trylock()
Try to lock the mutex.
void exec()
Execute the initialization function if not done yet.
Definition: Mutex.h:171
Wrapper around a pthreads mutex.
Definition: Mutex.h:49
Exception-safe lock/unlock of a mutex.
Definition: Mutex.h:97
Mutex & mutex()
Get the mutex (to make it possible to lock for other purposes).
Definition: Mutex.h:175
this file contains all the compiler specific defines
Definition: mainpage.dox:28
Mutex(Type type=Auto)
Create the mutex.