00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _LOG4TANGO_THREADING_PTHREADS_H
00029 #define _LOG4TANGO_THREADING_PTHREADS_H
00030
00031 #include <log4tango/Portability.hh>
00032 #include <stdio.h>
00033 #include <pthread.h>
00034 #include <string>
00035 #include <assert.h>
00036
00037 namespace log4tango {
00038
00039 namespace threading {
00040
00041 std::string get_thread_id (void);
00042
00043 long thread_id (void);
00044
00045
00046
00047
00048 class Mutex
00049 {
00050 private:
00051 pthread_mutex_t mutex;
00052
00053
00054 public:
00055 inline Mutex() {
00056 ::pthread_mutex_init(&mutex, NULL);
00057 }
00058
00059 inline ~Mutex() {
00060 ::pthread_mutex_destroy(&mutex);
00061 }
00062
00063 inline void lock() {
00064 ::pthread_mutex_lock(&mutex);
00065 }
00066
00067 inline void unlock() {
00068 ::pthread_mutex_unlock(&mutex);
00069 }
00070 };
00071
00072
00073
00074
00075 class ScopedLock
00076 {
00077 private:
00078 Mutex& _mutex;
00079
00080 public:
00081 inline ScopedLock(Mutex &m) : _mutex(m) {
00082 _mutex.lock();
00083 }
00084
00085 inline ~ScopedLock() {
00086 _mutex.unlock();
00087 }
00088 };
00089
00090
00091
00092
00093 class RecursiveMutex
00094 {
00095 public:
00096
00097 RecursiveMutex (void);
00098
00099
00100 ~RecursiveMutex (void);
00101
00102
00103
00104
00105
00106
00107
00108 int lock (long timeout_ = 0);
00109
00110
00111
00112
00113
00114
00115 void unlock (void);
00116 void unlockn (void);
00117
00118 protected:
00119
00120 pthread_mutex_t guard_;
00121
00122
00123
00124 pthread_cond_t mutex_available_;
00125
00126 private:
00127
00128 long recursion_level_;
00129
00130
00131 pthread_t owner_id_;
00132
00133
00134 RecursiveMutex (const RecursiveMutex&);
00135 RecursiveMutex& operator= (const RecursiveMutex&);
00136 };
00137
00138
00139
00140
00141 #ifdef LOG4TANGO_HAS_NDC
00142 template<typename T> class ThreadLocalDataHolder {
00143
00144 private:
00145 pthread_key_t _key;
00146
00147 public:
00148 typedef T data_type;
00149
00150 inline ThreadLocalDataHolder() {
00151 ::pthread_key_create(&_key, freeHolder);
00152 }
00153
00154 inline static void freeHolder(void *p) {
00155 assert(p != NULL);
00156 delete reinterpret_cast<T *>(p);
00157 }
00158
00159 inline ~ThreadLocalDataHolder() {
00160 T *data = get();
00161 if (data != NULL) {
00162 delete data;
00163 }
00164 ::pthread_key_delete(_key);
00165 }
00166
00167 inline T* get() const {
00168 return reinterpret_cast<T *>(::pthread_getspecific(_key));
00169 }
00170
00171 inline T* operator->() const { return get(); }
00172 inline T& operator*() const { return *get(); }
00173
00174 inline T* release() {
00175 T* result = get();
00176 ::pthread_setspecific(_key, NULL);
00177 return result;
00178 }
00179
00180 inline void reset(T* p = NULL) {
00181 T *data = get();
00182 if (data != NULL) {
00183 delete data;
00184 }
00185 ::pthread_setspecific(_key, p);
00186 }
00187 };
00188 #endif //LOG4TANGO_HAS_NDC
00189
00190 }
00191
00192 }
00193
00194 #endif // _LOG4TANGO_THREADING_PTHREADS_H