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.h>
25#include <core/threading/mutex_locker.h>
26
27namespace 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/** Constructor.
86 * @param mutex Mutex to lock/unlock appropriately.
87 * @param initially_lock true to lock the mutex in the constructor, false to not lock
88 */
89MutexLocker::MutexLocker(RefPtr<Mutex> mutex, bool initially_lock)
90{
91 rawmutex_ = 0;
92 refmutex_ = mutex;
93 if (initially_lock) {
94 refmutex_->lock();
95 }
96 locked_ = initially_lock;
97}
98
99/** Constructor.
100 * @param mutex Mutex to lock/unlock appropriately.
101 * @param initially_lock true to lock the mutex in the constructor, false to not lock
102 */
103MutexLocker::MutexLocker(Mutex *mutex, bool initially_lock)
104{
105 rawmutex_ = mutex;
106 if (initially_lock) {
107 rawmutex_->lock();
108 }
109 locked_ = initially_lock;
110}
111
112/** Constructor.
113 * @param mutex Mutex to lock/unlock appropriately.
114 * @param initially_lock true to lock the mutex in the constructor, false to not lock
115 */
116MutexLocker::MutexLocker(Mutex &mutex, bool initially_lock)
117{
118 rawmutex_ = &mutex;
119 if (initially_lock) {
120 rawmutex_->lock();
121 }
122 locked_ = initially_lock;
123}
124
125/** Destructor */
127{
128 if (locked_) {
129 if (rawmutex_) {
130 rawmutex_->unlock();
131 } else {
132 refmutex_->unlock();
133 }
134 }
135}
136
137/** Lock this mutex, again.
138 * Use this if you unlocked the mutex from the outside.
139 */
140void
142{
143 if (rawmutex_) {
144 rawmutex_->lock();
145 } else {
146 refmutex_->lock();
147 }
148 locked_ = true;
149}
150
151/** Unlock the mutex. */
152void
154{
155 locked_ = false;
156 if (rawmutex_) {
157 rawmutex_->unlock();
158 } else {
159 refmutex_->unlock();
160 }
161}
162
163} // end namespace fawkes
MutexLocker(RefPtr< Mutex > mutex, bool initially_lock=true)
Constructor.
~MutexLocker()
Destructor.
void relock()
Lock this mutex, again.
void unlock()
Unlock the mutex.
Mutex mutual exclusion lock.
Definition: mutex.h:33
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
RefPtr<> is a reference-counting shared smartpointer.
Definition: refptr.h:50
Fawkes library namespace.