Fawkes API  Fawkes Development Version
mutex_locker.cpp
1 
2 /***************************************************************************
3  * mutex_locker.cpp - mutex locker helper
4  *
5  * Created: Thu Oct 04 16:14:30 2007
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <core/threading/mutex_locker.h>
25 #include <core/threading/mutex.h>
26 
27 namespace fawkes {
28 
29 /** @class MutexLocker <core/threading/mutex_locker.h>
30  * Mutex locking helper.
31  * This class is a convenience function which can help you prevent a quite
32  * a few headaches. Consider the following code.
33  * @code
34  * void my_function()
35  * {
36  * mutex->lock();
37  * for (int i = 0; i < LIMIT; ++i) {
38  * if ( failure ) {
39  * mutex->unlock
40  * }
41  * }
42  *
43  * switch ( someval ) {
44  * VALA:
45  * mutex->unlock();
46  * return;
47  * VALB:
48  * do_something();
49  * }
50  *
51  * try {
52  * do_function_that_throws_exceptions();
53  * } catch (Exception &e) {
54  * mutex->unlock();
55  * throw;
56  * }
57  * mutex->unlock();
58  * }
59  * @endcode
60  * This is not a complete list of examples but as you see if you have many
61  * exit points in a function it becomes more and more work to have correct
62  * locking behavior.
63  *
64  * This is a lot simpler with the MutexLocker. The MutexLocker locks the
65  * given mutex on creation, and unlocks it in the destructor. If you now
66  * have a mutex locker on the stack as integral type the destructor is
67  * called automagically on function exit and thus the mutex is appropriately
68  * unlocked.
69  * The code would look like this:
70  * @code
71  * void my_function()
72  * {
73  * MutexLocker ml(mutex);
74  * // do anything, no need to call mutex->lock()/unlock() if only has to be
75  * // called on entering and exiting the function.
76  * }
77  * @endcode
78  *
79  * @ingroup Threading
80  * @ingroup FCL
81  *
82  * @author Tim Niemueller
83  */
84 
85 
86 /** Constructor.
87  * @param mutex Mutex to lock/unlock appropriately.
88  * @param initially_lock true to lock the mutex in the constructor, false to not lock
89  */
90 MutexLocker::MutexLocker(RefPtr<Mutex> mutex, bool initially_lock)
91 {
92  __rawmutex = 0;
93  __refmutex = mutex;
94  if ( initially_lock ) {
95  __refmutex->lock();
96  }
97  __locked = initially_lock;
98 }
99 
100 
101 /** Constructor.
102  * @param mutex Mutex to lock/unlock appropriately.
103  * @param initially_lock true to lock the mutex in the constructor, false to not lock
104  */
105 MutexLocker::MutexLocker(Mutex *mutex, bool initially_lock)
106 {
107  __rawmutex = mutex;
108  if ( initially_lock ) {
109  __rawmutex->lock();
110  }
111  __locked = initially_lock;
112 }
113 
114 
115 /** Destructor */
117 {
118  if ( __locked ) {
119  if ( __rawmutex) {
120  __rawmutex->unlock();
121  } else {
122  __refmutex->unlock();
123  }
124  }
125 }
126 
127 
128 /** Lock this mutex, again.
129  * Use this if you unlocked the mutex from the outside.
130  */
131 void
133 {
134  if ( __rawmutex ) {
135  __rawmutex->lock();
136  } else {
137  __refmutex->lock();
138  }
139  __locked = true;
140 }
141 
142 
143 /** Unlock the mutex. */
144 void
146 {
147  __locked = false;
148  if ( __rawmutex ) {
149  __rawmutex->unlock();
150  } else {
151  __refmutex->unlock();
152  }
153 }
154 
155 
156 } // end namespace fawkes
MutexLocker(RefPtr< Mutex > mutex, bool initially_lock=true)
Constructor.
Fawkes library namespace.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
void unlock()
Unlock the mutex.
void relock()
Lock this mutex, again.
~MutexLocker()
Destructor.
RefPtr<> is a reference-counting shared smartpointer.
Definition: refptr.h:49
void lock()
Lock this mutex.
Definition: mutex.cpp:89
Mutex mutual exclusion lock.
Definition: mutex.h:32