Mutex.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2010 Jacek Sieka, arnetheduck on gmail point com
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #ifndef ADCHPP_MUTEX_H_
00020 #define ADCHPP_MUTEX_H_
00021 
00022 #include "Thread.h"
00023 
00024 namespace adchpp {
00025 
00026 template<typename Mutex>
00027 class ScopedLock {
00028 public: 
00029     ScopedLock(Mutex& m_) : m(m_) { m.lock(); }
00030     ~ScopedLock() { m.unlock(); }
00031 private:
00032     Mutex& m;
00033     
00034 };
00035 
00036 #if defined(_WIN32)
00037 class RecursiveMutex : private boost::noncopyable {
00038 public:
00039     RecursiveMutex() { InitializeCriticalSection(&cs); }
00040     ~RecursiveMutex() { DeleteCriticalSection(&cs); }
00041     
00042     void lock() { EnterCriticalSection(&cs); }
00043     void unlock() { LeaveCriticalSection(&cs); }
00044     
00045     typedef ScopedLock<RecursiveMutex> Lock;
00046 private:
00047     CRITICAL_SECTION cs;
00048 };
00049 
00050 class FastMutex : private boost::noncopyable {
00051 public:
00052     FastMutex() : val(0) { }
00053     ~FastMutex() { }
00054     
00055     void lock() { while(InterlockedExchange(&val, 1) == 1) Thread::yield(); }
00056     void unlock() { InterlockedExchange(&val, 0); }
00057 
00058     typedef ScopedLock<FastMutex> Lock;
00059 private:
00060     long val;
00061 };
00062 
00063 #elif defined(HAVE_PTHREAD)
00064 
00065 class RecursiveMutex : private boost::noncopyable {
00066 public:
00067     RecursiveMutex() throw() {
00068         pthread_mutexattr_t attr;
00069         pthread_mutexattr_init(&attr);
00070         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00071         pthread_mutex_init(&mtx, &attr);
00072         pthread_mutexattr_destroy(&attr);
00073     }
00074     ~RecursiveMutex() throw() { pthread_mutex_destroy(&mtx); }
00075     void lock() throw() { pthread_mutex_lock(&mtx); }
00076     void unlock() throw() { pthread_mutex_unlock(&mtx); }
00077 
00078     typedef ScopedLock<RecursiveMutex> Lock;
00079 private:
00080     pthread_mutex_t mtx;
00081 };
00082 
00083 class FastMutex : private boost::noncopyable {
00084 public:
00085     FastMutex() throw() {
00086         pthread_mutexattr_t attr;
00087         pthread_mutexattr_init(&attr);
00088         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
00089         pthread_mutex_init(&mtx, &attr);
00090         pthread_mutexattr_destroy(&attr);
00091     }
00092     ~FastMutex() throw() { pthread_mutex_destroy(&mtx); }
00093     void lock() throw() { pthread_mutex_lock(&mtx); }
00094     void unlock() throw() { pthread_mutex_unlock(&mtx); }
00095 
00096     typedef ScopedLock<FastMutex> Lock;
00097 
00098 private:
00099     pthread_mutex_t mtx;
00100 };
00101 
00102 #else
00103 #error No mutex found
00104 #endif
00105 
00106 }
00107 
00108 #endif /*MUTEX_H_*/
Generated on Sat Nov 27 23:37:53 2010 for adchpp by  doxygen 1.6.3