/* Copyright (C) 2005-2009 Michel de Boer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "mutex.h" #include "thread.h" #include using namespace std; /////////////////////////// // t_mutex /////////////////////////// t_mutex::t_mutex() { pthread_mutex_init(&mutex, NULL); } t_mutex::t_mutex(bool recursive) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); if (ret != 0) throw string( "t_mutex::t_mutex failed to create a recursive mutex."); pthread_mutex_init(&mutex, &attr); pthread_mutexattr_destroy(&attr); } t_mutex::~t_mutex() { pthread_mutex_destroy(&mutex); } void t_mutex::lock(void) { int ret = pthread_mutex_lock(&mutex); if (ret != 0) throw string("t_mutex::lock failed."); } int t_mutex::trylock(void) { int ret = pthread_mutex_trylock(&mutex); switch (ret) { case 0: case EBUSY: return ret; default: throw string("t_mutex::trylock failed."); } } void t_mutex::unlock(void) { int ret = pthread_mutex_unlock(&mutex); if (ret != 0) throw ("t_mutex::unlock failed."); } /////////////////////////// // t_recursive_mutex /////////////////////////// t_recursive_mutex::t_recursive_mutex() : t_mutex(true) {} t_recursive_mutex::~t_recursive_mutex() {} /////////////////////////// // t_guard_mutex /////////////////////////// t_mutex_guard::t_mutex_guard(t_mutex &mutex) : mutex_(mutex) { mutex_.lock(); } t_mutex_guard::~t_mutex_guard() { mutex_.unlock(); } /////////////////////////// // t_rwmutex /////////////////////////// t_rwmutex::t_rwmutex() { int ret = pthread_rwlock_init(&_lock, nullptr); if (ret != 0) throw string( "t_rwmutex::t_rwmutex failed to create a r/w mutex."); } t_rwmutex::~t_rwmutex() { pthread_rwlock_destroy(&_lock); } void t_rwmutex::lockRead() { int err = pthread_rwlock_rdlock(&_lock); if (err != 0) throw std::logic_error("Mutex lock failed"); } void t_rwmutex::lockWrite() { int err = pthread_rwlock_wrlock(&_lock); if (err != 0) throw std::logic_error("Mutex lock failed"); } void t_rwmutex::unlock() { pthread_rwlock_unlock(&_lock); } /////////////////////////// // t_rwmutex_guard /////////////////////////// t_rwmutex_guard::t_rwmutex_guard(t_rwmutex& mutex) : _mutex(mutex) { } t_rwmutex_reader::t_rwmutex_reader(t_rwmutex& mutex) : t_rwmutex_guard(mutex) { // std::cout << "mtx rd lock " << (void*)&_mutex << std::endl; _mutex.lockRead(); } t_rwmutex_reader::~t_rwmutex_reader() { // std::cout << "mtx rd unlock " << (void*)&_mutex << std::endl; _mutex.unlock(); } t_rwmutex_writer::t_rwmutex_writer(t_rwmutex& mutex) : t_rwmutex_guard(mutex) { // std::cout << "mtx wr lock " << (void*)&_mutex << std::endl; _mutex.lockWrite(); } t_rwmutex_writer::~t_rwmutex_writer() { // std::cout << "mtx wr unlock " << (void*)&_mutex << std::endl; _mutex.unlock(); }