头文件duye_lock.h
/***********************************************************************************
**
* @copyright (c) 2010-2019, Technology Co., LTD. All Right Reserved.
*
************************************************************************************/
/**
* @file duye_lock.h
* @version
* @brief
* @author
* @date 2013-11-26
* @note
*
* 4. 2014-06-20 duye move to gohoop project
* 3. 2014-01-09 duye Add comments
* 2. 2014-01-04 duye
* a. Modify mutex function trylock to trylock()
* b. Add function trylock() for class orgLock
* c. Modify trylock class implimenting
*
* 1. 2013-11-26 Created this file
*/
#pragma once
#include <pthread.h>
#include <unistd.h>
#include <duye_type.h>
namespace duye {
/**
* @brief POSIX mutex wrapper
*/
class Mutex {
public:
/**
* @brief constructor
* @note default mutex type is PTHREAD_MUTEX_RECURSIVE
*/
Mutex();
/**
* @brief constructor
* @param [in] kind : mutex type
* @note have four mutex type, are PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_RECURSIVE
* PTHREAD_mutex_ERRORCHECK PTHREAD_MUTEX_DEFAULT
*/
explicit Mutex(const int32 kind);
virtual ~Mutex();
/**
* @brief lock mutex, enter to awaited state
* @return true/false
* @note
*/
bool lock();
/**
* @brief try to lock mutex, failure return immediately
* @return true/false
* @note
*/
bool tryLock();
/**
* @brief release lock
* @return true/false
* @note
*/
bool unlock();
private:
/**
* @brief to prevent copying
* @note
*/
Mutex(const Mutex&);
void operator=(const Mutex&);
/**
* @brief initialize mutex
* @param [in] kind : mutex type, reference constructor function
* @note
*/
void init(const int32 kind);
private:
pthread_mutex_t m_mutex;
};
/**
* try lock wrapper
*/
class TryLock {
public:
/**
* @brief constructor
* @param [in] mutex : mutex
* @param [in] autoUnlock : whether release lock automatic
* @note
*/
TryLock(Mutex& Mutex, const bool autoUnlock = true);
~TryLock();
/**
* @brief try lock
* @param [in] timeout : try lock timeout, default is zero, indicate try once,
* then return immediately
* @return true/false
* @note
*/
bool lock(const uint32 timeout = 0);
/**
* @brief release lock
* @return true/false
* @note if construct a release lock, invoke invalid
*/
bool unlock();
private:
/**
* @brief prevent copying
* @note
*/
TryLock(const TryLock&);
/**
* @brief prevent copying
* @note
*/
void operator=(const TryLock&);
private:
Mutex& m_mutex;
bool m_autoUnlock;
};
/**
* @brief auto lock wrapper
*/
class AutoLock {
public:
/**
* @brief constructor
* @param [in]mutex : mutex
* @note
*/
explicit AutoLock(Mutex& mutex);
~AutoLock();
private:
/**
* @brief prevent copying
* @note
*/
AutoLock(const AutoLock&);
/**
* @brief prevent copying
* @note
*/
void operator=(const AutoLock&);
private:
Mutex& m_mutex;
};
}
cpp文件duye_lock.cpp
/************************************************************************************
**
* @copyright (c) 2013-2100, Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file duye_lock.cpp
* @version
* @brief
* @author
* @date 2013-11-26
* @note
*
* 3. 2014-06-21 duye move to gohoop project
* 2. 2014-01-04 duye
* a. Change mutex function trylock() to trylock()
* b. Add function trylock() for orgLock class
* c. Modify trylock class implimenting
* 1. 2013-11-26 Created this file
*/
#include <duye_lock.h>
namespace duye {
Mutex::Mutex() {
init(PTHREAD_MUTEX_RECURSIVE);
}
Mutex::Mutex(const int32 kind) {
if (kind != PTHREAD_MUTEX_NORMAL &&
kind != PTHREAD_MUTEX_RECURSIVE &&
kind != PTHREAD_MUTEX_ERRORCHECK &&
kind != PTHREAD_MUTEX_DEFAULT) {
init(PTHREAD_MUTEX_DEFAULT);
} else {
init(kind);
}
}
Mutex::~Mutex() {
pthread_mutex_destroy(&m_mutex);
}
bool Mutex::lock() {
return pthread_mutex_lock(&m_mutex) == 0 ? true : false;
}
bool Mutex::tryLock() {
return pthread_mutex_trylock(&m_mutex) == 0 ? true : false;
}
bool Mutex::unlock() {
return pthread_mutex_unlock(&m_mutex) == 0 ? true : false;
}
void Mutex::init(const int32 kind) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, kind);
pthread_mutex_init(&m_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
TryLock::TryLock(Mutex& mutex, const bool autoUnlock) : m_mutex(mutex), m_autoUnlock(autoUnlock) {}
TryLock::~TryLock() {
if (m_autoUnlock) {
m_mutex.unlock();
}
}
bool TryLock::lock(const uint32 timeout) {
if (m_mutex.tryLock()) {
return true;
}
if (timeout == 0) {
return false;
}
const uint32 sleep_unit = 10;
uint32 loops = timeout / sleep_unit + 1;
do {
if (loops == 1) {
usleep(1000 * (timeout % sleep_unit));
} else {
usleep(1000 * sleep_unit);
}
if (m_mutex.tryLock()) {
return true;
}
} while(--loops);
return false;
}
bool TryLock::unlock() {
if (m_autoUnlock) {
return false;
}
return m_mutex.unlock();
}
AutoLock::AutoLock(Mutex& mutex) : m_mutex(mutex) {
m_mutex.lock();
}
AutoLock::~AutoLock() {
m_mutex.unlock();
}
}