log4shib
1.0.4
|
00001 /* 00002 * PThreads.hh 00003 * 00004 * Copyright 2002, Emiliano Martin emilianomc@terra.es All rights reserved. 00005 * 00006 * See the COPYING file for the terms of usage and distribution. 00007 */ 00008 00009 #ifndef _LOG4SHIB_THREADING_PTHREADS_HH 00010 #define _LOG4SHIB_THREADING_PTHREADS_HH 00011 00012 #include <log4shib/Portability.hh> 00013 #include <stdio.h> 00014 #include <pthread.h> 00015 #include <string> 00016 #include <assert.h> 00017 00018 00019 namespace log4shib { 00020 namespace threading { 00021 00025 std::string getThreadId(); 00026 00029 class Mutex { 00030 private: 00031 pthread_mutex_t mutex; 00032 00033 public: 00034 inline Mutex() { 00035 ::pthread_mutex_init(&mutex, NULL); 00036 } 00037 00038 inline void lock() { 00039 ::pthread_mutex_lock(&mutex); 00040 } 00041 00042 inline void unlock() { 00043 ::pthread_mutex_unlock(&mutex); 00044 } 00045 00046 inline ~Mutex() { 00047 ::pthread_mutex_destroy(&mutex); 00048 } 00049 00050 private: 00051 Mutex(const Mutex& m); 00052 Mutex& operator=(const Mutex &m); 00053 }; 00054 00058 class ScopedLock { 00059 private: 00060 Mutex& _mutex; 00061 00062 public: 00063 inline ScopedLock(Mutex& mutex) : 00064 _mutex(mutex) { 00065 _mutex.lock(); 00066 } 00067 00068 inline ~ScopedLock() { 00069 _mutex.unlock(); 00070 } 00071 }; 00072 00076 template<typename T> class ThreadLocalDataHolder { 00077 private: 00078 pthread_key_t _key; 00079 00080 public: 00081 typedef T data_type; 00082 00083 inline ThreadLocalDataHolder() { 00084 ::pthread_key_create(&_key, freeHolder); 00085 } 00086 00087 inline static void freeHolder(void *p) { 00088 assert(p != NULL); 00089 delete reinterpret_cast<T *>(p); 00090 } 00091 00092 inline ~ThreadLocalDataHolder() { 00093 T *data = get(); 00094 if (data != NULL) { 00095 delete data; 00096 } 00097 ::pthread_key_delete(_key); 00098 } 00099 00100 inline T* get() const { 00101 return reinterpret_cast<T *>(::pthread_getspecific(_key)); 00102 } 00103 00104 inline T* operator->() const { return get(); } 00105 inline T& operator*() const { return *get(); } 00106 00107 inline T* release() { 00108 T* result = get(); 00109 ::pthread_setspecific(_key, NULL); 00110 00111 return result; 00112 } 00113 00114 inline void reset(T* p = NULL) { 00115 T *data = get(); 00116 if (data != NULL) { 00117 delete data; 00118 } 00119 ::pthread_setspecific(_key, p); 00120 } 00121 }; 00122 00123 } 00124 } 00125 #endif