00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef _LOG4CPP_THREADING_PTHREADS_HH
00010 #define _LOG4CPP_THREADING_PTHREADS_HH
00011
00012 #include <log4cpp/Portability.hh>
00013 #include <stdio.h>
00014 #include <pthread.h>
00015 #include <string>
00016 #include <assert.h>
00017
00018
00019 namespace log4cpp {
00020 namespace threading {
00021
00025 static std::string getThreadId() {
00026 char buffer[16];
00027 ::sprintf(buffer, "%ld", pthread_self());
00028 return std::string(buffer);
00029 }
00030
00033 class Mutex {
00034 private:
00035 pthread_mutex_t mutex;
00036
00037 public:
00038 inline Mutex() {
00039 ::pthread_mutex_init(&mutex, NULL);
00040 }
00041
00042 inline void lock() {
00043 ::pthread_mutex_lock(&mutex);
00044 }
00045
00046 inline void unlock() {
00047 ::pthread_mutex_unlock(&mutex);
00048 }
00049
00050 inline ~Mutex() {
00051 ::pthread_mutex_destroy(&mutex);
00052 }
00053
00054 inline void operator=(const Mutex &m) {
00055 mutex = m.mutex;
00056 }
00057 };
00058
00062 class ScopedLock {
00063 private:
00064 Mutex _mutex;
00065
00066 public:
00067 inline ScopedLock(const Mutex &mutex) {
00068 _mutex = mutex;
00069 _mutex.lock();
00070 }
00071
00072 inline ~ScopedLock() {
00073 _mutex.unlock();
00074 }
00075 };
00076
00080 template<typename T> class ThreadLocalDataHolder {
00081 private:
00082 pthread_key_t _key;
00083
00084 public:
00085 typedef T data_type;
00086
00087 inline ThreadLocalDataHolder() {
00088 ::pthread_key_create(&_key, freeHolder);
00089 }
00090
00091 inline static void freeHolder(void *p) {
00092 assert(p != NULL);
00093 T *data = (T *) p;
00094 delete p;
00095 }
00096
00097 inline ~ThreadLocalDataHolder() {
00098 T *data = get();
00099 if (data != NULL) {
00100 delete data;
00101 }
00102 ::pthread_key_delete(_key);
00103 }
00104
00105 inline T* get() const {
00106 return (T *) ::pthread_getspecific(_key);
00107 }
00108
00109 inline T* operator->() const { return get(); }
00110 inline T& operator*() const { return *get(); }
00111
00112 inline T* release() {
00113 T* result = get();
00114 ::pthread_setspecific(_key, NULL);
00115
00116 return result;
00117 }
00118
00119 inline void reset(T* p = NULL) {
00120 T *data = get();
00121 if (data != NULL) {
00122 delete data;
00123 }
00124 ::pthread_setspecific(_key, p);
00125 }
00126 };
00127
00128 }
00129 }
00130 #endif