sprint 1-alpha
|
00001 /****************************************************************************** 00002 * sprint::mutex 00003 * 00004 * Copyright (C) 2003-2011 Paolo Medici <www.pmx.it> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 * 00020 *******************************************************************************/ 00021 00027 #ifndef _SPRINT_MUTEX_H 00028 #define _SPRINT_MUTEX_H 00029 00030 #include <sprint/sysdef.h> 00031 #include <sprint/cpptraits.h> 00032 00033 #ifndef WIN32 00034 # include <pthread.h> 00035 #endif 00036 00037 00038 namespace sprint { 00039 00047 template<class T> 00048 class scoped_lock { 00049 T & m_mutex; 00050 public: 00052 scoped_lock(T & m) : m_mutex(m) { m_mutex.lock(); } 00054 ~scoped_lock() { m_mutex.unlock(); } 00055 }; 00056 00057 #ifdef WIN32 00058 00063 #define USE_CRITICAL_SECTION 00064 00065 /* ************************************* WIN32 ******************************* */ 00066 00067 #ifdef USE_CRITICAL_SECTION 00068 00070 class mutex: public sprint::uncopiable { 00071 private: 00072 CRITICAL_SECTION m_cs; 00073 public: 00074 typedef sprint::scoped_lock<sprint::mutex> scoped_lock; 00075 public: 00076 inline mutex() 00077 { 00078 ::InitializeCriticalSection(&m_cs); 00079 } 00080 inline ~mutex() 00081 { 00082 ::DeleteCriticalSection(&m_cs); 00083 } 00085 inline void lock() 00086 { 00087 ::EnterCriticalSection (&m_cs); 00088 } 00090 inline void unlock() 00091 { 00092 ::LeaveCriticalSection( &m_cs ); 00093 } 00094 00095 }; 00096 00097 #else 00098 00100 class mutex: public sprint::uncopiable { 00101 private: 00102 HANDLE m_mutex; 00103 00105 mutex(const mutex & src) { } 00106 public: 00107 typedef sprint::scoped_lock<sprint::mutex> scoped_lock; 00108 public: 00109 inline mutex() 00110 { 00111 m_mutex = ::CreateMutex(NULL, FALSE, NULL); 00112 } 00113 inline ~mutex() 00114 { 00115 ::CloseHandle(m_mutex); 00116 } 00117 00118 inline bool lock(unsigned int timeout = INFINITE) 00119 { 00120 return ::WaitForSingleObject(m_mutex, timeout) == WAIT_OBJECT_0; 00121 } 00122 00123 inline bool unlock() 00124 { 00125 return ::ReleaseMutex(m_mutex); 00126 } 00127 00128 inline HANDLE operator HANDLE() 00129 { 00130 return m_mutex; 00131 } 00132 00133 }; 00134 00135 #endif 00136 00138 typedef mutex thread_mutex; 00139 00140 #else // LINUX 00141 00143 class mutex: public sprint::uncopiable { 00144 private: 00145 pthread_mutex_t m_mutex; 00146 public: 00147 typedef sprint::scoped_lock<sprint::mutex> scoped_lock; 00148 public: 00149 mutex() 00150 { 00151 pthread_mutexattr_t attr; 00152 00153 pthread_mutexattr_init(&attr); 00154 00155 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); 00156 00157 pthread_mutex_init(&m_mutex, &attr); 00158 00159 pthread_mutexattr_destroy(&attr); 00160 } 00161 00162 ~mutex() 00163 { 00164 pthread_mutex_destroy(&m_mutex); 00165 } 00166 00167 inline bool lock() 00168 { 00169 return pthread_mutex_lock(&m_mutex); 00170 } 00171 00172 inline void unlock() 00173 { 00174 pthread_mutex_unlock(&m_mutex); 00175 } 00176 00177 inline pthread_mutex_t gethandle() 00178 { 00179 return m_mutex; 00180 } 00181 00182 }; 00183 00184 #endif // WIN32 00185 00186 00187 } // namespace sprint 00188 00189 00190 #endif // _PM_MUTEX_