4.5.1r9
[enigma2.git] / usr / include / enigma2 / lib / base / elock.h
1 #ifndef __elock_h
2 #define __elock_h
3
4 #include <sys/syscall.h>
5 #include <pthread.h>
6 #include <lib/base/sigc.h>
7
8 class singleLock
9 {
10         pthread_mutex_t &lock;
11 public:
12         singleLock(pthread_mutex_t &m ) __attribute__ ((always_inline))
13                 :lock(m)
14         {
15                 pthread_mutex_lock(&lock);
16         }
17         ~singleLock() __attribute__ ((always_inline))
18         {
19                 pthread_mutex_unlock(&lock);
20         }
21 };
22
23 class eRdWrLock
24 {
25         friend class eRdLocker;
26         friend class eWrLocker;
27         pthread_rwlock_t m_lock;
28         eRdWrLock(eRdWrLock &);
29 public:
30         eRdWrLock() __attribute__ ((always_inline))
31         {
32                 pthread_rwlock_init(&m_lock, 0);
33         }
34         ~eRdWrLock() __attribute__ ((always_inline))
35         {
36                 pthread_rwlock_destroy(&m_lock);
37         }
38         void RdLock() __attribute__ ((always_inline))
39         {
40                 pthread_rwlock_rdlock(&m_lock);
41         }
42         void WrLock() __attribute__ ((always_inline))
43         {
44                 pthread_rwlock_wrlock(&m_lock);
45         }
46         void Unlock() __attribute__ ((always_inline))
47         {
48                 pthread_rwlock_unlock(&m_lock);
49         }
50 };
51
52 class eRdLocker
53 {
54         eRdWrLock &m_lock;
55 public:
56         eRdLocker(eRdWrLock &m) __attribute__ ((always_inline))
57                 : m_lock(m)
58         {
59                 pthread_rwlock_rdlock(&m_lock.m_lock);
60         }
61         ~eRdLocker() __attribute__ ((always_inline))
62         {
63                 pthread_rwlock_unlock(&m_lock.m_lock);
64         }
65 };
66
67 class eWrLocker
68 {
69         eRdWrLock &m_lock;
70 public:
71         eWrLocker(eRdWrLock &m) __attribute__ ((always_inline))
72                 : m_lock(m)
73         {
74                 pthread_rwlock_wrlock(&m_lock.m_lock);
75         }
76         ~eWrLocker() __attribute__ ((always_inline))
77         {
78                 pthread_rwlock_unlock(&m_lock.m_lock);
79         }
80 };
81
82 class eSpinLock
83 {
84         pthread_spinlock_t m_lock;
85         pid_t m_owner;
86         unsigned long m_locked;
87 public:
88         static pid_t gettid()
89         {
90                 static __thread bool tid_read;
91                 static __thread pid_t tid;
92                 if (!tid_read) {
93                         tid_read = true;
94                         tid = syscall(SYS_gettid);
95                 }
96                 return tid;
97         }
98
99         eSpinLock()
100                 :m_owner(-1), m_locked(0)
101         {
102                 pthread_spin_init(&m_lock, 0);
103         }
104         ~eSpinLock() __attribute__ ((always_inline))
105         {
106                 pthread_spin_destroy(&m_lock);
107         }
108
109         void lock() __attribute__ ((always_inline))
110         {
111                 pid_t caller = gettid();
112                 if (caller != m_owner) {
113                         pthread_spin_lock(&m_lock);
114                         m_owner = caller;
115                 }
116                 ++m_locked;
117         }
118         bool tryLock() __attribute__ ((always_inline))
119         {
120                 return pthread_spin_trylock(&m_lock) == 0;
121         }
122         void unlock() __attribute__ ((always_inline))
123         {
124                 if (gettid() == m_owner) {
125                         if (!--m_locked) {
126                                 m_owner = -1;
127                                 pthread_spin_unlock(&m_lock);
128                         }
129                 }
130         }
131 };
132
133 class eSpinLocker
134 {
135         eSpinLock &m_lock;
136 public:
137         eSpinLocker(eSpinLock &m) __attribute__ ((always_inline))
138                 : m_lock(m)
139         {
140                 m_lock.lock();
141         }
142         ~eSpinLocker() __attribute__ ((always_inline))
143         {
144                 m_lock.unlock();
145         }
146 };
147
148 /* FIXME: rename to eMutex */
149 class eSingleLock
150 {
151         pthread_mutex_t m_lock;
152 public:
153         eSingleLock(bool recursive=false)
154         {
155                 if (recursive)
156                 {
157                         pthread_mutexattr_t attr;
158                         pthread_mutexattr_init(&attr);
159                         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
160                         pthread_mutex_init(&m_lock, &attr);
161                         pthread_mutexattr_destroy(&attr);
162                 }
163                 else
164                         pthread_mutex_init(&m_lock, 0);
165         }
166         ~eSingleLock() __attribute__ ((always_inline))
167         {
168                 pthread_mutex_destroy(&m_lock);
169         }
170
171         void lock() __attribute__ ((always_inline))
172         {
173                 pthread_mutex_lock(&m_lock);
174         }
175         bool tryLock() __attribute__ ((always_inline))
176         {
177                 return pthread_mutex_trylock(&m_lock) == 0;
178         }
179         void unlock() __attribute__ ((always_inline))
180         {
181                 pthread_mutex_unlock(&m_lock);
182         }
183 };
184
185 class eSingleLocker
186 {
187         eSingleLock &m_lock;
188 public:
189         eSingleLocker(eSingleLock &m) __attribute__ ((always_inline))
190                 : m_lock(m)
191         {
192                 m_lock.lock();
193         }
194         ~eSingleLocker() __attribute__ ((always_inline))
195         {
196                 m_lock.unlock();
197         }
198 };
199
200 class eLock
201 {
202         pthread_mutex_t m_mutex;
203         pthread_cond_t m_cond;
204
205         int m_counter, m_max;
206 public:
207         void lock(int res);
208         void lock(int res, const sigc::slot<bool> &abort_wait_cond);
209         void recheck_cond() { pthread_cond_signal(&m_cond); }
210         void unlock(int res);
211         int trylock(int res, bool force=false);
212         int counter() const { return m_counter; }
213         void setMax(int max) { m_max = max; }
214         int max() const { return m_max; }
215
216         eLock(int max);
217         ~eLock();
218 };
219
220 class eSemaphore
221 {
222         int v;
223         pthread_mutex_t mutex;
224         pthread_cond_t cond;
225 public:
226         eSemaphore(int val=1);
227         ~eSemaphore();
228         
229         /*
230          * with timeout 0 it waits until internal
231          * value is > 0 else until timeout expired
232          * or value changed
233          */
234         int down(int timeout_msec=0);
235         int decrement();
236         int up();
237         int value();
238 };
239
240 #endif