2c2b5c569819a669353712c1968cfa14bab9cbae
[deb_libcec.git] / src / lib / platform / threads / mutex.h
1 #pragma once
2 /*
3 * This file is part of the libCEC(R) library.
4 *
5 * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
6 * libCEC(R) is an original work, containing original code.
7 *
8 * libCEC(R) is a trademark of Pulse-Eight Limited.
9 *
10 * This program is dual-licensed; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 *
25 * Alternatively, you can license this library under a commercial license,
26 * please contact Pulse-Eight Licensing for more information.
27 *
28 * For more information contact:
29 * Pulse-Eight Licensing <license@pulse-eight.com>
30 * http://www.pulse-eight.com/
31 * http://www.pulse-eight.net/
32 */
33
34 namespace PLATFORM
35 {
36 class PreventCopy
37 {
38 public:
39 inline PreventCopy(void) {}
40 inline ~PreventCopy(void) {}
41
42 private:
43 inline PreventCopy(const PreventCopy &c) { *this = c; }
44 inline PreventCopy &operator=(const PreventCopy &c){ *this = c; return *this; }
45 };
46
47 class CCondition;
48
49 class CMutex : public PreventCopy
50 {
51 friend class CCondition;
52 public:
53 inline CMutex(void) :
54 m_iLockCount(0)
55 {
56 MutexCreate(m_mutex);
57 }
58
59 inline ~CMutex(void)
60 {
61 Clear();
62 MutexDelete(m_mutex);
63 }
64
65 inline bool TryLock(void)
66 {
67 if (MutexTryLock(m_mutex))
68 {
69 ++m_iLockCount;
70 return true;
71 }
72 return false;
73 }
74
75 inline bool Lock(void)
76 {
77 MutexLock(m_mutex);
78 ++m_iLockCount;
79 return true;
80 }
81
82 inline void Unlock(void)
83 {
84 if (Lock())
85 {
86 if (m_iLockCount >= 2)
87 {
88 --m_iLockCount;
89 MutexUnlock(m_mutex);
90 }
91
92 --m_iLockCount;
93 MutexUnlock(m_mutex);
94 }
95 }
96
97 inline bool Clear(void)
98 {
99 bool bReturn(false);
100 if (TryLock())
101 {
102 unsigned int iLockCount = m_iLockCount;
103 for (unsigned int iPtr = 0; iPtr < iLockCount; iPtr++)
104 Unlock();
105 bReturn = true;
106 }
107 return bReturn;
108 }
109
110 private:
111 mutex_t m_mutex;
112 volatile unsigned int m_iLockCount;
113 };
114
115 class CLockObject : public PreventCopy
116 {
117 public:
118 inline CLockObject(CMutex &mutex, bool bClearOnExit = false) :
119 m_mutex(mutex),
120 m_bClearOnExit(bClearOnExit)
121 {
122 m_mutex.Lock();
123 }
124
125 inline ~CLockObject(void)
126 {
127 if (m_bClearOnExit)
128 Clear();
129 else
130 Unlock();
131 }
132
133 inline bool TryLock(void)
134 {
135 return m_mutex.TryLock();
136 }
137
138 inline void Unlock(void)
139 {
140 m_mutex.Unlock();
141 }
142
143 inline bool Clear(void)
144 {
145 return m_mutex.Clear();
146 }
147
148 inline bool Lock(void)
149 {
150 return m_mutex.Lock();
151 }
152
153 private:
154 CMutex &m_mutex;
155 bool m_bClearOnExit;
156 };
157
158 class CCondition : public PreventCopy
159 {
160 public:
161 inline CCondition(void)
162 {
163 ConditionCreate(m_condition);
164 }
165
166 inline ~CCondition(void)
167 {
168 Broadcast();
169 ConditionDelete(m_condition);
170 }
171
172 inline void Broadcast(void)
173 {
174 ConditionBroadcast(m_condition);
175 }
176
177 inline void Signal(void)
178 {
179 ConditionSignal(m_condition);
180 }
181
182 inline bool Wait(CMutex &mutex, uint32_t iTimeout = 0)
183 {
184 return ConditionWait(m_condition, mutex.m_mutex, iTimeout);
185 }
186
187 static void Sleep(uint32_t iTimeout)
188 {
189 CCondition w;
190 CMutex m;
191 CLockObject lock(m);
192 w.Wait(m, iTimeout);
193 }
194
195 condition_t m_condition;
196 };
197 }