00001 /* -*- mode: c++; indent-tabs-mode: nil -*- */ 00002 /* 00003 QoreThreadLock.h 00004 00005 Qore Programming Language 00006 00007 Copyright (C) 2003 - 2010 David Nichols, all rights reserved 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00022 */ 00023 00024 #ifndef _QORE_QORETHREADLOCK_H 00025 00026 #define _QORE_QORETHREADLOCK_H 00027 00028 #include <pthread.h> 00029 00030 #include <assert.h> 00031 00033 00036 class QoreThreadLock { 00037 friend class QoreCondition; 00038 00039 private: 00041 pthread_mutex_t ptm_lock; 00042 00044 DLLLOCAL QoreThreadLock& operator=(const QoreThreadLock&); 00045 00047 DLLLOCAL void init() { 00048 #ifndef NDEBUG 00049 int rc = 00050 #endif 00051 pthread_mutex_init(&ptm_lock, 0); 00052 assert(!rc); 00053 } 00054 00055 public: 00057 DLLLOCAL QoreThreadLock() { 00058 init(); 00059 } 00060 00062 DLLLOCAL ~QoreThreadLock() { 00063 pthread_mutex_destroy(&ptm_lock); 00064 } 00065 00067 DLLLOCAL QoreThreadLock(const QoreThreadLock&) { 00068 init(); 00069 } 00070 00072 00074 DLLLOCAL void lock() { 00075 #ifndef NDEBUG 00076 int rc = 00077 #endif 00078 pthread_mutex_lock(&ptm_lock); 00079 assert(!rc); 00080 } 00081 00083 00085 DLLLOCAL void unlock() { 00086 #ifndef NDEBUG 00087 int rc = 00088 #endif 00089 pthread_mutex_unlock(&ptm_lock); 00090 assert(!rc); 00091 } 00092 00094 00097 DLLLOCAL int trylock() { 00098 return pthread_mutex_trylock(&ptm_lock); 00099 } 00100 }; 00101 00103 00109 class AutoLocker { 00110 private: 00112 DLLLOCAL AutoLocker(const AutoLocker&); 00113 00115 DLLLOCAL AutoLocker& operator=(const AutoLocker&); 00116 00118 DLLLOCAL void *operator new(size_t); 00119 00120 protected: 00122 QoreThreadLock *lck; 00123 00124 public: 00126 DLLLOCAL AutoLocker(QoreThreadLock *l) : lck(l) { 00127 lck->lock(); 00128 } 00129 00131 DLLLOCAL AutoLocker(QoreThreadLock &l) : lck(&l) { 00132 lck->lock(); 00133 } 00134 00136 DLLLOCAL ~AutoLocker() { 00137 lck->unlock(); 00138 } 00139 }; 00140 00142 00148 class SafeLocker { 00149 private: 00151 DLLLOCAL SafeLocker(const SafeLocker&); 00152 00154 DLLLOCAL SafeLocker& operator=(const SafeLocker&); 00155 00157 DLLLOCAL void *operator new(size_t); 00158 00159 protected: 00161 QoreThreadLock *lck; 00162 00164 bool locked; 00165 00166 public: 00168 DLLEXPORT SafeLocker(QoreThreadLock *l) : lck(l) { 00169 lck->lock(); 00170 locked = true; 00171 } 00172 00174 DLLEXPORT SafeLocker(QoreThreadLock &l) : lck(&l) { 00175 lck->lock(); 00176 locked = true; 00177 } 00178 00180 DLLEXPORT ~SafeLocker() { 00181 if (locked) 00182 lck->unlock(); 00183 } 00184 00186 DLLEXPORT void lock() { 00187 assert(!locked); 00188 lck->lock(); 00189 locked = true; 00190 } 00191 00193 DLLEXPORT void unlock() { 00194 assert(locked); 00195 locked = false; 00196 lck->unlock(); 00197 } 00198 00200 DLLEXPORT void stay_locked() { 00201 assert(locked); 00202 locked = false; 00203 } 00204 }; 00205 00206 #endif // _QORE_QORETHREADLOCK_H