log4tango  5.0.1
PThreads.hh
Go to the documentation of this file.
1 //
2 // PThreads.hh
3 //
4 // Copyright (C) : 2000 - 2002
5 // LifeLine Networks BV (www.lifeline.nl). All rights reserved.
6 // Bastiaan Bakker. All rights reserved.
7 //
8 // 2004,2005,2006,2007,2008,2009,2010,2011,2012
9 // Synchrotron SOLEIL
10 // L'Orme des Merisiers
11 // Saint-Aubin - BP 48 - France
12 //
13 // This file is part of log4tango.
14 //
15 // Log4ango is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU Lesser General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // Log4tango is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU Lesser General Public License for more details.
24 //
25 // You should have received a copy of the GNU Lesser General Public License
26 // along with Log4Tango. If not, see <http://www.gnu.org/licenses/>.
27 
28 #ifndef _LOG4TANGO_THREADING_PTHREADS_H
29 #define _LOG4TANGO_THREADING_PTHREADS_H
30 
31 #include <log4tango/Portability.hh>
32 #include <stdio.h>
33 #include <pthread.h>
34 #include <string>
35 #include <assert.h>
36 
37 namespace log4tango {
38 
39 namespace threading {
40 
41 std::string get_thread_id (void);
42 
43 long thread_id (void);
44 
45 //-----------------------------------------------------------------------------
46 // Class : Mutex
47 //-----------------------------------------------------------------------------
48 class Mutex
49 {
50 private:
51  pthread_mutex_t mutex;
52 
53 
54 public:
55  inline Mutex() {
56  ::pthread_mutex_init(&mutex, NULL);
57  }
58 
59  inline ~Mutex() {
60  ::pthread_mutex_destroy(&mutex);
61  }
62 
63  inline void lock() {
64  ::pthread_mutex_lock(&mutex);
65  }
66 
67  inline void unlock() {
68  ::pthread_mutex_unlock(&mutex);
69  }
70 };
71 
72 //-----------------------------------------------------------------------------
73 // Class : ScopedLock
74 //-----------------------------------------------------------------------------
75 class ScopedLock
76 {
77 private:
78  Mutex& _mutex;
79 
80 public:
81  inline ScopedLock(Mutex &m) : _mutex(m) {
82  _mutex.lock();
83  }
84 
85  inline ~ScopedLock() {
86  _mutex.unlock();
87  }
88 };
89 
90 //-----------------------------------------------------------------------------
91 // Class : RecursiveMutex
92 //-----------------------------------------------------------------------------
93 class RecursiveMutex
94 {
95 public:
96  // ctor
97  RecursiveMutex (void);
98 
99  // dtor
100  ~RecursiveMutex (void);
101 
102  // Locking an RecursiveMutex:
103  // If <timeout_> is null (the default), <lock> blocks until
104  // the mutex is acquired and returns 1 (true). Otherwise,
105  // <lock> blocks until the mutex is acquired or times out
106  // after <timeout_> milliseconds in which case 0 (false) is
107  // returned.
108  int lock (long timeout_ = 0);
109 
110  // Releasing an RecursiveMutex:
111  // Call unlock <recursion level> times (i.e. one call for
112  // each previous call to lock) or call unlockn just once.
113  // These two methods do nothing if the caller is not the
114  // current owner of the mutex.
115  void unlock (void);
116  void unlockn (void);
117 
118 protected:
119  // guards the <recursion level> and <owner id>
120  pthread_mutex_t guard_;
121 
122  // this condition variable suspends other waiting threads
123  // until the mutex is available
124  pthread_cond_t mutex_available_;
125 
126 private:
127  // current level of the recursion
128  long recursion_level_;
129 
130  // current owner of the lock.
131  pthread_t owner_id_;
132 
133  // dummy copy constructor and operator= to prevent copying
135  RecursiveMutex& operator= (const RecursiveMutex&);
136 };
137 
138 //-----------------------------------------------------------------------------
139 // Class : ThreadLocalDataHolder
140 //-----------------------------------------------------------------------------
141 #ifdef LOG4TANGO_HAS_NDC
142 template<typename T> class ThreadLocalDataHolder {
143 
144 private:
145  pthread_key_t _key;
146 
147 public:
148  typedef T data_type;
149 
150  inline ThreadLocalDataHolder() {
151  ::pthread_key_create(&_key, freeHolder);
152  }
153 
154  inline static void freeHolder(void *p) {
155  assert(p != NULL);
156  delete reinterpret_cast<T *>(p);
157  }
158 
159  inline ~ThreadLocalDataHolder() {
160  T *data = get();
161  if (data != NULL) {
162  delete data;
163  }
164  ::pthread_key_delete(_key);
165  }
166 
167  inline T* get() const {
168  return reinterpret_cast<T *>(::pthread_getspecific(_key));
169  }
170 
171  inline T* operator->() const { return get(); }
172  inline T& operator*() const { return *get(); }
173 
174  inline T* release() {
175  T* result = get();
176  ::pthread_setspecific(_key, NULL);
177  return result;
178  }
179 
180  inline void reset(T* p = NULL) {
181  T *data = get();
182  if (data != NULL) {
183  delete data;
184  }
185  ::pthread_setspecific(_key, p);
186  }
187 };
188 #endif //LOG4TANGO_HAS_NDC
189 
190 } // namespace threading
191 
192 } // namespace log4tango
193 
194 #endif // _LOG4TANGO_THREADING_PTHREADS_H
Definition: Appender.hh:40
pthread_cond_t mutex_available_
Definition: PThreads.hh:124
pthread_mutex_t guard_
Definition: PThreads.hh:120
Definition: MSThreads.hh:100
Definition: MSThreads.hh:123
int Mutex
Definition: DummyThreads.hh:41
void unlock()
Definition: PThreads.hh:67
~Mutex()
Definition: PThreads.hh:59
Mutex()
Definition: PThreads.hh:55
ScopedLock(Mutex &m)
Definition: PThreads.hh:81
~ScopedLock()
Definition: PThreads.hh:85
std::string get_thread_id(void)
Definition: DummyThreads.cpp:37
void lock()
Definition: PThreads.hh:63
Definition: MSThreads.hh:74