Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lock.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_CORE_LOCK_H_)
21 #define __MITSUBA_CORE_LOCK_H_
22 
23 #include <mitsuba/mitsuba.h>
24 
25 #include <boost/scoped_ptr.hpp>
26 
28 
29 /**
30  * \brief Thin wrapper around the recursive boost thread lock
31  *
32  * \ingroup libcore
33  */
34 class MTS_EXPORT_CORE Mutex : public Object {
35  friend class ConditionVariable;
36 public:
37  /// Create a new mutex object
38  Mutex();
39 
40  /// Lock the mutex
41  void lock();
42 
43  /// Unlock the mutex
44  void unlock();
45 
47 protected:
48  /// Virtual destructor
49  virtual ~Mutex();
50 private:
51  struct MutexPrivate;
52  boost::scoped_ptr<MutexPrivate> d;
53 };
54 
55 /**
56  * \brief Wait flag synchronization primitive. Can be used to
57  * wait for a certain event to occur.
58  *
59  * \ingroup libcore
60  */
62 public:
63  /**
64  * \brief Create a new wait flag
65  * \param flag
66  * Initial state of the flag. If set to true, \ref wait()
67  * will immediately return.
68  */
69  WaitFlag(bool flag = false);
70 
71  /// Return the current flag value
72  const bool &get() const;
73 
74  /// Set the value of the flag
75  void set(bool value);
76 
77  /// Wait for the flag to be set to true
78  void wait();
79 
80  /**
81  * \brief Temporarily wait for the flag to be set to true
82  *
83  * Similar to \ref wait(), but also uses a time value given
84  * in milliseconds. A return value of \c false signals
85  * that a timeout has occurred.
86  *
87  * \param ms Maximum waiting time in milliseconds
88  */
89  bool wait(int ms);
90 
92 protected:
93  /// Virtual destructor
94  virtual ~WaitFlag();
95 private:
96  struct WaitFlagPrivate;
97  boost::scoped_ptr<WaitFlagPrivate> d;
98 };
99 
100 /**
101  * \brief Condition variable synchronization primitive. Can be used to
102  * wait for a condition to become true in a safe way.
103  *
104  * \ingroup libcore
105  */
106 class MTS_EXPORT_CORE ConditionVariable : public Object {
107 public:
108  /**
109  * \brief Create a new condition variable. Also takes a
110  * mutex, which is later used by wait(). If none is specified,
111  * a new mutex instance will be created.
112  */
113  ConditionVariable(Mutex *mutex = NULL);
114 
115  /**
116  * \brief Send a signal, which wakes up at least one of
117  * the waiting threads.
118  *
119  * The calling thread does not have to hold the lock,
120  * but more predictable scheduling will occur if this is the
121  * case.
122  */
123  void signal();
124 
125  /**
126  * \brief Send a signal, which wakes up any waiting threads.
127  *
128  * The calling thread does not have to hold the lock, but more
129  * predictable scheduling will occur if this is the case.
130  */
131  void broadcast();
132 
133  /**
134  * \brief Wait for a signal and release the lock in the meanwhile.
135  *
136  * Assumes that the lock specified in the constructor has
137  * previously been acquired. After returning, the lock is
138  * held again.
139  */
140  void wait();
141 
142  /**
143  * \brief Temporarily wait for a signal and release the lock in the meanwhile.
144  *
145  * Similar to wait(), but also uses a time value given
146  * in milliseconds. A return value of \c false signals
147  * that a timeout has occurred. The lock is held after
148  * returning in either case.
149  *
150  * \param ms Maximum waiting time in milliseconds
151  */
152  bool wait(int ms);
153 
155 protected:
156  /// Virtual destructor
157  virtual ~ConditionVariable();
158 private:
159  struct ConditionVariablePrivate;
160  boost::scoped_ptr<ConditionVariablePrivate> d;
161 };
162 
163 /**
164  * \brief Simple RAII-style locking of a Mutex. On construction it locks the
165  * mutex and unlocks it on destruction. Based on boost::lock_guard,
166  * assumes the Mutex will outlive the lock.
167  *
168  * \ingroup libcore
169  */
170 class LockGuard {
171 public:
172  explicit LockGuard(Mutex * m_) : m(m_) {
173  m->lock();
174  }
175 
177  m->unlock();
178  }
179 private:
180  Mutex* const m;
181 
182  explicit LockGuard(LockGuard&);
183  LockGuard& operator=(LockGuard&);
184 };
185 
186 /**
187  * \brief In addition to providing RAII-style locking, UniqueLock also allows
188  * for deferred locking until lock() is called explicitly. unlock() is only
189  * called by the destructor if the object has locked the mutex.
190  * Based on boost::unique_lock, assumes the Mutex will outlive the lock.
191  */
192 class UniqueLock {
193 public:
194  explicit UniqueLock(Mutex * mutex, bool acquire_lock = true)
195  : m(mutex), is_locked(false) {
196  if (acquire_lock)
197  lock();
198  }
199 
201  if (ownsLock())
202  m->unlock();
203  }
204 
205  void lock() {
206  SAssert(!ownsLock() && m != NULL);
207  m->lock();
208  is_locked = true;
209  }
210 
211  void unlock() {
212  SAssert(ownsLock() && m != NULL);
213  m->unlock();
214  is_locked = false;
215  }
216 
217  Mutex * release() {
218  Mutex * const mutex = m;
219  m = static_cast<Mutex*>(NULL);
220  is_locked = false;
221  return mutex;
222  }
223 
224  inline bool operator!() const {
225  return !ownsLock();
226  }
227 
228  inline bool ownsLock() const {
229  return is_locked;
230  }
231 
232 private:
233  Mutex* m;
234  bool is_locked;
235 
236  explicit UniqueLock(UniqueLock&);
237  UniqueLock& operator=(UniqueLock&);
238 };
239 
241 
242 #endif /* __MITSUBA_CORE_LOCK_H_ */
Mutex * release()
Definition: lock.h:217
bool ownsLock() const
Definition: lock.h:228
Condition variable synchronization primitive. Can be used to wait for a condition to become true in a...
Definition: lock.h:106
UniqueLock(Mutex *mutex, bool acquire_lock=true)
Definition: lock.h:194
#define MTS_EXPORT_CORE
Definition: getopt.h:29
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
void unlock()
Definition: lock.h:211
Simple RAII-style locking of a Mutex. On construction it locks the mutex and unlocks it on destructio...
Definition: lock.h:170
~UniqueLock()
Definition: lock.h:200
#define SAssert(cond)
``Static&#39;&#39; assertion (to be used outside of classes that derive from Object)
Definition: logger.h:79
#define MTS_DECLARE_CLASS()
This macro must be used in the initial definition in classes that derive from Object.
Definition: class.h:158
bool operator!() const
Definition: lock.h:224
LockGuard(Mutex *m_)
Definition: lock.h:172
Wait flag synchronization primitive. Can be used to wait for a certain event to occur.
Definition: lock.h:61
void lock()
Definition: lock.h:205
Parent of all Mitsuba classes.
Definition: object.h:38
~LockGuard()
Definition: lock.h:176
#define MTS_NAMESPACE_END
Definition: platform.h:138
Thin wrapper around the recursive boost thread lock.
Definition: lock.h:34
In addition to providing RAII-style locking, UniqueLock also allows for deferred locking until lock()...
Definition: lock.h:192