Fawkes API Fawkes Development Version
mutex.cpp
1
2/***************************************************************************
3 * mutex.cpp - implementation of mutex, based on pthreads
4 *
5 * Generated: Thu Sep 14 17:03:57 2006
6 * Copyright 2006 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/exception.h>
25#include <core/threading/mutex.h>
26#include <core/threading/mutex_data.h>
27#include <core/threading/thread.h>
28
29#include <pthread.h>
30
31namespace fawkes {
32
33/** @class Mutex core/threading/mutex.h
34 * Mutex mutual exclusion lock.
35 * This class is used in a multi-threading environment to lock access to
36 * resources. This is needed to prevent two threads from modifying a value
37 * at the same time or to prevent a thread from getting a dirty copy of
38 * a piece of data (the reader reads while a writer is writing, this could
39 * leave the data in a state where the reader reads half of the new and half
40 * of the old data).
41 *
42 * As a rule of thumb you should lock the mutex as short as possible and as
43 * long as needed. Locking the mutex too long will lead in a bad performance
44 * of the multi-threaded application because many threads are waiting for
45 * the lock and are not doing anything useful.
46 * If you do not lock enough code (and so serialize it) it will cause pain
47 * and errors.
48 *
49 * @ingroup Threading
50 * @ingroup FCL
51 * @see example_mutex_count.cpp
52 *
53 * @author Tim Niemueller
54 */
55
56/** Constructor.
57 * @param type mutex type
58 */
60{
61 mutex_data = new MutexData();
62
63 pthread_mutexattr_t attr;
64 pthread_mutexattr_init(&attr);
65 if (type == RECURSIVE) {
66 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
67 } else {
68 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
69 }
70
71 pthread_mutex_init(&(mutex_data->mutex), &attr);
72}
73
74/** Destructor */
76{
77 pthread_mutex_destroy(&(mutex_data->mutex));
78 delete mutex_data;
79 mutex_data = NULL;
80}
81
82/** Lock this mutex.
83 * A call to lock() will block until the lock on the mutex could be aquired.
84 * If you want to avoid see consider using try_lock().
85 */
86void
88{
89 int err = 0;
90 if ((err = pthread_mutex_lock(&(mutex_data->mutex))) != 0) {
91 throw Exception(err, "Failed to aquire lock for thread %s", Thread::current_thread()->name());
92 }
93#ifdef DEBUG_THREADING
94 // do not switch order, lock holder must be protected with this mutex!
95 mutex_data->set_lock_holder();
96#endif
97}
98
99/** Tries to lock the mutex.
100 * This can also be used to check if a mutex is locked. The code for this
101 * can be:
102 *
103 * @code
104 * bool locked = false;
105 * if ( mutex->try_lock() ) {
106 * mutex->unlock();
107 * locked = true;
108 * }
109 * @endcode
110 *
111 * This cannot be implemented in Mutex in a locked() method since this
112 * would lead to race conditions in many situations.
113 *
114 * @return true, if the mutex could be locked, false otherwise.
115 */
116bool
118{
119 if (pthread_mutex_trylock(&(mutex_data->mutex)) == 0) {
120#ifdef DEBUG_THREADING
121 mutex_data->set_lock_holder();
122#endif
123 return true;
124 } else {
125 return false;
126 }
127}
128
129/** Unlock the mutex. */
130void
132{
133#ifdef DEBUG_THREADING
134 mutex_data->unset_lock_holder();
135 // do not switch order, lock holder must be protected with this mutex!
136#endif
137 pthread_mutex_unlock(&(mutex_data->mutex));
138}
139
140/** Shortly stop by at the mutex.
141 * This will just lock and unlock the mutex. It is equivalent to
142 * @code
143 * mutex->lock();
144 * mutex->unlock();
145 * @endcode
146 * This can be handy if you have to protect starvation and just have a stop-by
147 * mutex.
148 */
149void
151{
152 pthread_mutex_lock(&(mutex_data->mutex));
153 pthread_mutex_unlock(&(mutex_data->mutex));
154}
155
156} // end namespace fawkes
Base class for exceptions in Fawkes.
Definition: exception.h:36
~Mutex()
Destructor.
Definition: mutex.cpp:75
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:117
Type
Mutex type.
Definition: mutex.h:38
@ RECURSIVE
A thread attempting to relock this mutex without first unlocking it shall succeed in locking the mute...
Definition: mutex.h:40
void lock()
Lock this mutex.
Definition: mutex.cpp:87
void stopby()
Shortly stop by at the mutex.
Definition: mutex.cpp:150
void unlock()
Unlock the mutex.
Definition: mutex.cpp:131
Mutex(Type type=NORMAL)
Constructor.
Definition: mutex.cpp:59
static Thread * current_thread()
Get the Thread instance of the currently running thread.
Definition: thread.cpp:1366
Fawkes library namespace.