[DEBUG] missing recursive mutex
This commit is contained in:
parent
4a38787d22
commit
8ee819a6e1
99
ethread/MutexRecursive.hpp
Normal file
99
ethread/MutexRecursive.hpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
|
||||||
|
#ifdef __TARGET_OS__Windows
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ethread {
|
||||||
|
/**
|
||||||
|
* @brief Generic mutex interface (OS independent)
|
||||||
|
*/
|
||||||
|
// TODO: Create a single class parametrable for all mutex ...
|
||||||
|
class MutexRecursive {
|
||||||
|
private:
|
||||||
|
#ifdef __TARGET_OS__Windows
|
||||||
|
CRITICAL_SECTION m_mutex;
|
||||||
|
#else
|
||||||
|
pthread_mutex_t m_mutex;
|
||||||
|
pthread_mutexattr_t m_attribute;
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG
|
||||||
|
uint32_t m_threadThatHaveLock;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Create a new mutex recursive
|
||||||
|
*/
|
||||||
|
MutexRecursive();
|
||||||
|
/**
|
||||||
|
* @brief Destroy the mutex.
|
||||||
|
*/
|
||||||
|
~MutexRecursive();
|
||||||
|
/**
|
||||||
|
* @brief Lock the mutex (Wait while the mutex is not lock)
|
||||||
|
*/
|
||||||
|
void lock();
|
||||||
|
/**
|
||||||
|
* @brief Try to lock the mutex (exit if mutex is already locked)
|
||||||
|
* @return true The mutex is locked
|
||||||
|
* @return false The mutex is already locked.
|
||||||
|
*/
|
||||||
|
bool tryLock();
|
||||||
|
/**
|
||||||
|
* @brief Unloc the mutex
|
||||||
|
*/
|
||||||
|
void unLock();
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief AutoLock and un-lock when exit fuction.
|
||||||
|
*/
|
||||||
|
class RecursiveLock {
|
||||||
|
private:
|
||||||
|
// Keep a reference on the mutex
|
||||||
|
ethread::MutexRecursive &m_protect;
|
||||||
|
bool m_lock;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief constructor that automaticly lock the mutex.
|
||||||
|
* @param[in] _protect Mutex to Lock.
|
||||||
|
* @param[in] _notLock Must be lock after by a tryLock.
|
||||||
|
*/
|
||||||
|
RecursiveLock(ethread::MutexRecursive& _protect, bool _notLock = false) :
|
||||||
|
m_protect(_protect),
|
||||||
|
m_lock(false) {
|
||||||
|
if (_notLock == false) {
|
||||||
|
m_protect.lock();
|
||||||
|
m_lock = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Try to lock the mutex (exit if mutex is already locked)
|
||||||
|
* @return true The mutex is locked
|
||||||
|
* @return false The mutex is already locked.
|
||||||
|
*/
|
||||||
|
bool tryLock() {
|
||||||
|
if (m_protect.tryLock() == true) {
|
||||||
|
m_lock = true;
|
||||||
|
}
|
||||||
|
return m_lock;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Destructor that Auto Unlock mutex when remove.
|
||||||
|
*/
|
||||||
|
virtual ~RecursiveLock(){
|
||||||
|
if (m_lock == true) {
|
||||||
|
m_protect.unLock();
|
||||||
|
m_lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
89
ethread/MutexRecursive.pthread.cpp
Normal file
89
ethread/MutexRecursive.pthread.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <ethread/MutexRecursive.hpp>
|
||||||
|
#include <ethread/tools.hpp>
|
||||||
|
extern "C" {
|
||||||
|
#include <errno.h>
|
||||||
|
}
|
||||||
|
#include <etk/typeInfo.hpp>
|
||||||
|
ETK_DECLARE_TYPE(ethread::MutexRecursive);
|
||||||
|
ETK_DECLARE_TYPE(ethread::RecursiveLock);
|
||||||
|
//#include <ethread/debug.hpp>
|
||||||
|
|
||||||
|
ethread::MutexRecursive::MutexRecursive() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
m_threadThatHaveLock = 0xFFFFFFFF;
|
||||||
|
#endif
|
||||||
|
// create interface mutex :
|
||||||
|
pthread_mutexattr_init(&m_attribute);
|
||||||
|
pthread_mutexattr_settype(&m_attribute, PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
int ret = pthread_mutex_init(&m_mutex, &m_attribute);
|
||||||
|
//ETHREAD_ASSERT(ret == 0, "Error creating Mutex ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ethread::MutexRecursive::~MutexRecursive() {
|
||||||
|
// Remove mutex
|
||||||
|
int ret = pthread_mutex_destroy(&m_mutex);
|
||||||
|
//ETHREAD_ASSERT(ret == 0, "Error destroying Mutex ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ethread::MutexRecursive::lock() {
|
||||||
|
pthread_mutex_lock(&m_mutex);
|
||||||
|
#ifdef DEBUG
|
||||||
|
m_threadThatHaveLock = ethread::getId();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ethread::MutexRecursive::tryLock() {
|
||||||
|
int ret = pthread_mutex_trylock(&m_mutex);
|
||||||
|
if (ret == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ret == EINVAL) {
|
||||||
|
printf("trylock error: EINVAL\n");
|
||||||
|
// The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's
|
||||||
|
// priority is higher than the mutex's current priority ceiling.
|
||||||
|
// The pthread_mutex_trylock() function shall fail if:
|
||||||
|
}
|
||||||
|
if (ret == EBUSY) {
|
||||||
|
printf("trylock error: EBUSY\n");
|
||||||
|
// The mutex could not be acquired because it was already locked.
|
||||||
|
// The pthread_mutex_lock(), pthread_mutex_trylock(), and pthread_mutex_unlock() functions may fail if:
|
||||||
|
}
|
||||||
|
if (ret == EINVAL) {
|
||||||
|
printf("trylock error: EINVAL\n");
|
||||||
|
// The value specified by mutex does not refer to an initialized mutex object.
|
||||||
|
}
|
||||||
|
if (ret == EAGAIN) {
|
||||||
|
printf("trylock error: EAGAIN\n");
|
||||||
|
// The mutex could not be acquired because the maximum number of recursive locks for mutex has been exceeded.
|
||||||
|
// The pthread_mutex_lock() function may fail if:
|
||||||
|
}
|
||||||
|
if (ret == EDEADLK) {
|
||||||
|
printf("trylock error: EDEADLK\n");
|
||||||
|
// The current thread already owns the mutex.
|
||||||
|
// The pthread_mutex_unlock() function may fail if:
|
||||||
|
}
|
||||||
|
if (ret == EPERM) {
|
||||||
|
printf("trylock error: EPERM\n");
|
||||||
|
//The current thread does not own the mutex.
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ethread::MutexRecursive::unLock() {
|
||||||
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
#ifdef DEBUG
|
||||||
|
m_threadThatHaveLock = 0xFFFFFFFF;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user