You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cpp_utils/test/main_standalone_Mutex_Scope...

207 lines
4.1 KiB

#include <iostream>
#ifndef NOTRACE
#define TRACE(x) std::cout << x << " " << __PRETTY_FUNCTION__ << \
" : " << __LINE__ << std::endl
#else
/// @todo Get rid of the "warning: statement has no effect" compiler msgs
#define TRACE(x) ""
#endif
#include <assert.h>
#include <pthread.h>
#include <stdexcept>
#include <time.h>
class Mutex
{
public:
Mutex() {
TRACE(this);
int ret = pthread_mutex_init( &m_mutex, 0 );
// assert( ret == 0 );
}
~Mutex() {
TRACE(this);
int ret = pthread_mutex_destroy ( &m_mutex );
// assert( ret == 0 );
}
void lock() {
TRACE(this);
int ret = pthread_mutex_lock( &m_mutex );
// assert( ret == 0 );
}
void unlock() {
TRACE(this);
int ret = pthread_mutex_unlock( &m_mutex );
// assert( ret == 0 );
}
// private:
Mutex(const Mutex& m){
TRACE(this);
}
Mutex& operator=(const Mutex& m) {
TRACE(this);
return *this;
}
int tryLock() {
TRACE(this);
// return pthread_mutex_trylock(&m_mutex);
int interval = 1;
timespec abs_time;
clock_gettime ( CLOCK_REALTIME, &abs_time );
abs_time.tv_nsec += interval * 1000000;
if ( abs_time.tv_nsec >= 1000000000 ) {
abs_time.tv_nsec -= 1000000000;
abs_time.tv_sec += 1;
}
return pthread_mutex_timedlock ( &m_mutex, &abs_time );
}
private:
pthread_mutex_t m_mutex;
};
class BadScopedLock
{
public:
BadScopedLock(Mutex& m)
: m_mutex(m) /// @note cctor called!
{
TRACE(this);
m_mutex.lock();
}
~BadScopedLock() {
TRACE(this);
m_mutex.unlock();
}
private:
BadScopedLock(const BadScopedLock&);
BadScopedLock& operator=(const BadScopedLock&);
Mutex& m_mutex;
};
class UnluckyUser
{
public:
UnluckyUser() : m_mutex() {
TRACE(this);
}
~UnluckyUser() {
TRACE(this);
}
void fv() {
TRACE(this);
BadScopedLock sl(m_mutex);
throw std::logic_error("whoops");
}
int tryLock() {
TRACE(this);
return m_mutex.tryLock();
}
private:
Mutex m_mutex;
};
// class GoodScopedLock
// {
// public:
//
// GoodScopedLock(Mutex* m) : m_mutex(m)
// {
// TRACE(this);
// m_mutex->lock();
// }
// ~GoodScopedLock() {
// TRACE(this);
// m_mutex->unlock();
// }
//
// private:
// GoodScopedLock(const GoodScopedLock&);
// GoodScopedLock& operator=(const GoodScopedLock&);
//
// Mutex* m_mutex;
// };
/*
class LuckyUser
{
public:
LuckyUser() : m_mutex() {
TRACE(this);
}
~LuckyUser() {
TRACE(this);
}
void fv() {
TRACE(this);
GoodScopedLock sl(&m_mutex);
throw std::logic_error("whoops");
}
int tryLock() {
TRACE(this);
return m_mutex.tryLock();
}
private:
Mutex m_mutex;
};*/
int main()
{
TRACE("main begin");
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// // pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
// std::cout << "bla1" << std::endl;
// std::cout << pthread_mutex_unlock( &mutex )<< std::endl;
// std::cout << pthread_mutex_trylock( &mutex ) << std::endl;
// std::cout << "bla2" << std::endl;
// // std::cout << pthread_mutex_unlock( &mutex ) << std::endl;
//
// std::cout << "bla3" << std::endl;
//
// std::cout << pthread_mutex_lock( &mutex ) << std::endl;
// std::cout << pthread_mutex_trylock( &mutex ) << std::endl;
// // std::cout << pthread_mutex_lock( &mutex ) << std::endl;
UnluckyUser u;
try {
u.fv();
} catch (std::logic_error ex) {
std::cout << "std::logicexception: " << ex.what() << std::endl;
if (u.tryLock() == 0) {
std::cout << "UnluckyUser: Ok, mutex is unlocked" << std::endl;
} else {
std::cout << "UnluckyUser: Failed, mutex is still locked" << std::endl;
}
}
// TRACE("main middle");
//
// LuckyUser u2;
// try {
// u2.fv();
// } catch (std::logic_error ex) {
// std::cout << "std::logicexception: " << ex.what() << std::endl;
// if (u2.tryLock() == 0) {
// std::cout << "LuckyUser: Ok, mutex is unlocked" << std::endl;
// } else {
// std::cout << "LuckyUser: Failed, mutex is still locked" << std::endl;
// }
// }
TRACE("main end");
return 0;
}