/* * PThreads.hh * * Copyright 2002, Emiliano Martin emilianomc@terra.es All rights reserved. * * See the COPYING file for the terms of usage and distribution. */ #ifndef _LOG4CPP_THREADING_PTHREADS_HH #define _LOG4CPP_THREADING_PTHREADS_HH #include #include #include #include #include LOG4CPP_NS_BEGIN namespace threading { /** * returns the thread ID **/ std::string getThreadId(); /** **/ #if defined(VXWORKS) class Mutex { private: SEM_ID m_sem; public: inline Mutex() { m_sem = semMCreate( SEM_Q_PRIORITY | SEM_INVERSION_SAFE ); } inline void lock() { STATUS result = semTake( m_sem, WAIT_FOREVER ); if (result != OK) { // throw here? } } inline void unlock() { semGive( m_sem ); } inline ~Mutex() { semDelete( m_sem ); } private: Mutex(const Mutex& m); Mutex& operator=(const Mutex &m); }; #else class Mutex { private: pthread_mutexattr_t mutexattr; pthread_mutex_t mutex; public: inline Mutex() { ::pthread_mutexattr_init(&mutexattr); ::pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); ::pthread_mutex_init(&mutex, &mutexattr); } inline void lock() { ::pthread_mutex_lock(&mutex); } inline void unlock() { ::pthread_mutex_unlock(&mutex); } inline ~Mutex() { ::pthread_mutex_destroy(&mutex); ::pthread_mutexattr_destroy(&mutexattr); } private: Mutex(const Mutex& m); Mutex& operator=(const Mutex &m); }; #endif /** * definition of ScopedLock; **/ class ScopedLock { private: Mutex& _mutex; public: inline ScopedLock(Mutex& mutex) : _mutex(mutex) { _mutex.lock(); } inline ~ScopedLock() { _mutex.unlock(); } }; /** * **/ template class ThreadLocalDataHolder { private: pthread_key_t _key; public: typedef T data_type; inline ThreadLocalDataHolder() { ::pthread_key_create(&_key, freeHolder); } inline static void freeHolder(void *p) { assert(p != NULL); delete reinterpret_cast(p); } inline ~ThreadLocalDataHolder() { T *data = get(); if (data != NULL) { delete data; } ::pthread_key_delete(_key); } inline T* get() const { return reinterpret_cast(::pthread_getspecific(_key)); } inline T* operator->() const { return get(); } inline T& operator*() const { return *get(); } inline T* release() { T* result = get(); ::pthread_setspecific(_key, NULL); return result; } inline void reset(T* p = NULL) { T *data = get(); if (data != NULL) { delete data; } ::pthread_setspecific(_key, p); } }; } LOG4CPP_NS_END #endif