|
libpsynth 0.2.1
|
00001 /*************************************************************************** 00002 * * 00003 * PSYCHOSYNTH * 00004 * =========== * 00005 * * 00006 * Copyright (C) 2007 by Juan Pedro Bolivar Puente * 00007 * * 00008 * This program is free software: you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation, either version 3 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00020 * * 00021 ***************************************************************************/ 00022 00023 #ifndef PSYNTH_MUTEX_H 00024 #define PSYNTH_MUTEX_H 00025 00026 #include <pthread.h> 00027 #include <errno.h> 00028 00029 namespace psynth 00030 { 00031 00043 class mutex 00044 { 00045 friend class condition; 00046 00047 pthread_mutex_t m_mutex; 00048 pthread_mutexattr_t attr; 00049 00050 void init (int type) { 00051 pthread_mutexattr_init(&attr); 00052 pthread_mutexattr_settype(&attr, type); 00053 pthread_mutex_init(&m_mutex, &attr); 00054 } 00055 00056 void destroy () { 00057 pthread_mutexattr_destroy(&attr); 00058 pthread_mutex_destroy(&m_mutex); 00059 } 00060 00061 public: 00062 00066 enum type { 00068 DEFAULT = PTHREAD_MUTEX_DEFAULT, 00070 FAST = PTHREAD_MUTEX_NORMAL, 00072 RECURSIVE = PTHREAD_MUTEX_RECURSIVE, 00074 ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK 00075 }; 00076 00081 mutex (int type = DEFAULT) { 00082 init(type); 00083 } 00084 00086 ~mutex () { 00087 destroy(); 00088 } 00089 00094 void reset (int type = DEFAULT) { 00095 destroy(); 00096 init(type); 00097 } 00098 00104 bool lock () const { 00105 if (pthread_mutex_lock((pthread_mutex_t*) &m_mutex) == EDEADLK) 00106 return true; 00107 return false; 00108 } 00109 00115 bool try_lock () const { 00116 if (pthread_mutex_trylock((pthread_mutex_t*)&m_mutex) == EBUSY) 00117 return false; 00118 return true; 00119 } 00120 00121 #if 0 00122 bool timed_lock (const timespec& delay) const { 00123 if (pthread_mutex_timedlock_np((pthread_mutex_t*)&m_mutex, &delay) == EBUSY) 00124 return false; 00125 return true; 00126 } 00127 #endif 00128 00132 void unlock() const { 00133 pthread_mutex_unlock((pthread_mutex_t*)&m_mutex); 00134 } 00135 }; 00136 00142 class rwlock 00143 { 00144 pthread_rwlock_t m_rwlock; 00145 // pthread_rwlockattr_t attr; 00146 00147 void init (int type) { 00148 /* 00149 pthread_rwlockattr_init(&attr); 00150 pthread_rwlockattr_settype(&attr, type); 00151 */ 00152 pthread_rwlock_init(&m_rwlock, NULL); 00153 } 00154 00155 void destroy () { 00156 /* 00157 pthread_rwlockattr_destroy(&attr); 00158 */ 00159 pthread_rwlock_destroy(&m_rwlock); 00160 } 00161 00162 public: 00163 enum type { 00164 DEFAULT 00165 #if 0 00166 00167 DEFAULT = PTHREAD_RWLOCK_DEFAULT, 00169 PREFER_READER = PTHREAD_RWLOCK_PREFER_READER, 00171 PREFER_WRITER = PTHREAD_RWLOCK_PREFER_WRITER, 00173 N_TYPE 00174 #endif 00175 }; 00176 00181 rwlock(int type = DEFAULT) { 00182 init(type); 00183 } 00184 00186 ~rwlock() { 00187 destroy(); 00188 } 00189 00195 void read_lock() const { 00196 pthread_rwlock_rdlock((pthread_rwlock_t*)&m_rwlock); 00197 } 00198 00203 void write_lock() const { 00204 pthread_rwlock_wrlock((pthread_rwlock_t*)&m_rwlock); 00205 } 00206 00212 bool try_read_lock() const { 00213 if (pthread_rwlock_tryrdlock((pthread_rwlock_t*)&m_rwlock) == EBUSY) 00214 return false; 00215 return true; 00216 } 00217 00223 bool try_write_lock() { 00224 if (pthread_rwlock_trywrlock((pthread_rwlock_t*)&m_rwlock) == EBUSY) 00225 return false; 00226 return true; 00227 } 00228 00229 #if 0 00230 bool timed_read_lock(const struct timespec* delay) const { 00231 if (pthread_rwlock_timedrdlock_np((pthread_rwlock_t*)&m_rwlock, delay) == EBUSY) 00232 return false; 00233 return true; 00234 } 00235 00236 bool timed_write_lock(const timespec& delay) const { 00237 if (pthread_rwlock_timedwrlock_np((pthread_rwlock_t*)&m_rwlock, &delay) == EBUSY) 00238 return false; 00239 return true; 00240 } 00241 #endif 00242 00246 void unlock () const { 00247 pthread_rwlock_unlock((pthread_rwlock_t*)&m_rwlock); 00248 } 00249 }; 00250 00254 class condition 00255 { 00256 pthread_cond_t cond; 00257 00258 public: 00260 condition () { 00261 pthread_cond_init(&cond, NULL); 00262 } 00263 00265 ~condition () { 00266 pthread_cond_destroy(&cond); 00267 } 00268 00272 void broadcast () const { 00273 pthread_cond_broadcast((pthread_cond_t*)&cond); 00274 } 00275 00279 void signal () const { 00280 pthread_cond_signal((pthread_cond_t*)&cond); 00281 } 00282 00289 void wait (mutex& mutex) const { 00290 pthread_cond_wait((pthread_cond_t*)&cond, 00291 (pthread_mutex_t*)&mutex.m_mutex); 00292 } 00293 00303 bool timed_wait(mutex& mutex, const timespec& abstime) const { 00304 if (pthread_cond_timedwait((pthread_cond_t*)&cond, 00305 (pthread_mutex_t*)&mutex.m_mutex, 00306 &abstime) == ETIMEDOUT) 00307 return false; 00308 return true; 00309 } 00310 00311 #if 0 00312 static void calc_expiration(const timespec& delta, 00313 timespec& abstime) const { 00314 pthread_get_expiration_np(&delta, &abstime); 00315 } 00316 #endif 00317 }; 00318 00319 } /* namespace psynth */ 00320 00321 #endif /* PSYNTH_MUTEX_H */
1.7.4