DISTRHO Plugin Framework
 All Classes Functions Variables Modules Pages
d_mutex.hpp
1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
6  * or without fee is hereby granted, provided that the above copyright notice and this
7  * permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef DISTRHO_MUTEX_HPP_INCLUDED
18 #define DISTRHO_MUTEX_HPP_INCLUDED
19 
20 #include "../DistrhoUtils.hpp"
21 
22 #ifdef DISTRHO_OS_WINDOWS
23 # include <winsock2.h>
24 # include <windows.h>
25 #endif
26 
27 #include <pthread.h>
28 
29 START_NAMESPACE_DISTRHO
30 
31 // -----------------------------------------------------------------------
32 // Mutex class
33 
34 class Mutex
35 {
36 public:
37  /*
38  * Constructor.
39  */
40  Mutex() noexcept
41  {
42  pthread_mutex_init(&fMutex, nullptr);
43  }
44 
45  /*
46  * Destructor.
47  */
48  ~Mutex() noexcept
49  {
50  pthread_mutex_destroy(&fMutex);
51  }
52 
53  /*
54  * Lock the mutex.
55  */
56  void lock() const noexcept
57  {
58  pthread_mutex_lock(&fMutex);
59  }
60 
61  /*
62  * Try to lock the mutex.
63  * Returns true if successful.
64  */
65  bool tryLock() const noexcept
66  {
67  return (pthread_mutex_trylock(&fMutex) == 0);
68  }
69 
70  /*
71  * Unlock the mutex.
72  */
73  void unlock() const noexcept
74  {
75  pthread_mutex_unlock(&fMutex);
76  }
77 
78 private:
79  mutable pthread_mutex_t fMutex;
80 
81  DISTRHO_PREVENT_HEAP_ALLOCATION
82  DISTRHO_DECLARE_NON_COPY_CLASS(Mutex)
83 };
84 
85 // -----------------------------------------------------------------------
86 // RecursiveMutex class
87 
89 {
90 public:
91  /*
92  * Constructor.
93  */
94  RecursiveMutex() noexcept
95  {
96 #ifdef DISTRHO_OS_WINDOWS
97  InitializeCriticalSection(&fSection);
98 #else
99  pthread_mutexattr_t atts;
100  pthread_mutexattr_init(&atts);
101  pthread_mutexattr_settype(&atts, PTHREAD_MUTEX_RECURSIVE);
102  pthread_mutex_init(&fMutex, &atts);
103  pthread_mutexattr_destroy(&atts);
104 #endif
105  }
106 
107  /*
108  * Destructor.
109  */
110  ~RecursiveMutex() noexcept
111  {
112 #ifdef DISTRHO_OS_WINDOWS
113  DeleteCriticalSection(&fSection);
114 #else
115  pthread_mutex_destroy(&fMutex);
116 #endif
117  }
118 
119  /*
120  * Lock the mutex.
121  */
122  void lock() const noexcept
123  {
124 #ifdef DISTRHO_OS_WINDOWS
125  EnterCriticalSection(&fSection);
126 #else
127  pthread_mutex_lock(&fMutex);
128 #endif
129  }
130 
131  /*
132  * Try to lock the mutex.
133  * Returns true if successful.
134  */
135  bool tryLock() const noexcept
136  {
137 #ifdef DISTRHO_OS_WINDOWS
138  return (TryEnterCriticalSection(&fSection) != FALSE);
139 #else
140  return (pthread_mutex_trylock(&fMutex) == 0);
141 #endif
142  }
143 
144  /*
145  * Unlock the mutex.
146  */
147  void unlock() const noexcept
148  {
149 #ifdef DISTRHO_OS_WINDOWS
150  LeaveCriticalSection(&fSection);
151 #else
152  pthread_mutex_unlock(&fMutex);
153 #endif
154  }
155 
156 private:
157 #ifdef DISTRHO_OS_WINDOWS
158  mutable CRITICAL_SECTION fSection;
159 #else
160  mutable pthread_mutex_t fMutex;
161 #endif
162 
163  DISTRHO_PREVENT_HEAP_ALLOCATION
164  DISTRHO_DECLARE_NON_COPY_CLASS(RecursiveMutex)
165 };
166 
167 // -----------------------------------------------------------------------
168 // Helper class to lock&unlock a mutex during a function scope.
169 
170 template <class Mutex>
172 {
173 public:
174  ScopedLocker(const Mutex& mutex) noexcept
175  : fMutex(mutex)
176  {
177  fMutex.lock();
178  }
179 
180  ~ScopedLocker() noexcept
181  {
182  fMutex.unlock();
183  }
184 
185 private:
186  const Mutex& fMutex;
187 
188  DISTRHO_PREVENT_HEAP_ALLOCATION
189  DISTRHO_DECLARE_NON_COPY_CLASS(ScopedLocker)
190 };
191 
192 // -----------------------------------------------------------------------
193 // Helper class to unlock&lock a mutex during a function scope.
194 
195 template <class Mutex>
197 {
198 public:
199  ScopedUnlocker(const Mutex& mutex) noexcept
200  : fMutex(mutex)
201  {
202  fMutex.unlock();
203  }
204 
205  ~ScopedUnlocker() noexcept
206  {
207  fMutex.lock();
208  }
209 
210 private:
211  const Mutex& fMutex;
212 
213  DISTRHO_PREVENT_HEAP_ALLOCATION
214  DISTRHO_DECLARE_NON_COPY_CLASS(ScopedUnlocker)
215 };
216 
217 // -----------------------------------------------------------------------
218 // Define types
219 
222 
225 
226 // -----------------------------------------------------------------------
227 
228 END_NAMESPACE_DISTRHO
229 
230 #endif // DISTRHO_MUTEX_HPP_INCLUDED
Definition: d_mutex.hpp:88
Definition: d_mutex.hpp:196
Definition: d_mutex.hpp:34
Definition: d_mutex.hpp:171