blob: 13013cfbbd08ee26e1f8859abb085e64b7929ba6 [file] [log] [blame]
Pierre Ossman687d52c2015-11-12 12:16:08 +01001/* Copyright 2015 Pierre Ossman for Cendio AB
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19#ifdef WIN32
20#include <windows.h>
21#else
22#include <pthread.h>
23#endif
24
25#include <rdr/Exception.h>
26
27#include <os/Mutex.h>
28
29using namespace os;
30
31Mutex::Mutex()
32{
33#ifdef WIN32
34 systemMutex = new CRITICAL_SECTION;
35 InitializeCriticalSection((CRITICAL_SECTION*)systemMutex);
36#else
37 int ret;
38
39 systemMutex = new pthread_mutex_t;
40 ret = pthread_mutex_init((pthread_mutex_t*)systemMutex, NULL);
41 if (ret != 0)
42 throw rdr::SystemException("Failed to create mutex", ret);
43#endif
44}
45
46Mutex::~Mutex()
47{
48#ifdef WIN32
49 DeleteCriticalSection((CRITICAL_SECTION*)systemMutex);
50 delete (CRITICAL_SECTION*)systemMutex;
51#else
Pierre Ossmanca0c5f52017-09-15 15:40:47 +020052 pthread_mutex_destroy((pthread_mutex_t*)systemMutex);
Pierre Ossman687d52c2015-11-12 12:16:08 +010053 delete (pthread_mutex_t*)systemMutex;
Pierre Ossman687d52c2015-11-12 12:16:08 +010054#endif
55}
56
57void Mutex::lock()
58{
59#ifdef WIN32
60 EnterCriticalSection((CRITICAL_SECTION*)systemMutex);
61#else
62 int ret;
63
64 ret = pthread_mutex_lock((pthread_mutex_t*)systemMutex);
65 if (ret != 0)
66 throw rdr::SystemException("Failed to lock mutex", ret);
67#endif
68}
69
70void Mutex::unlock()
71{
72#ifdef WIN32
73 LeaveCriticalSection((CRITICAL_SECTION*)systemMutex);
74#else
75 int ret;
76
77 ret = pthread_mutex_unlock((pthread_mutex_t*)systemMutex);
78 if (ret != 0)
79 throw rdr::SystemException("Failed to unlock mutex", ret);
80#endif
81}
82
83Condition::Condition(Mutex* mutex)
84{
85 this->mutex = mutex;
86
87#ifdef WIN32
88 systemCondition = new CONDITION_VARIABLE;
89 InitializeConditionVariable((CONDITION_VARIABLE*)systemCondition);
90#else
91 int ret;
92
93 systemCondition = new pthread_cond_t;
94 ret = pthread_cond_init((pthread_cond_t*)systemCondition, NULL);
95 if (ret != 0)
96 throw rdr::SystemException("Failed to create condition variable", ret);
97#endif
98}
99
100Condition::~Condition()
101{
102#ifdef WIN32
103 delete (CONDITION_VARIABLE*)systemCondition;
104#else
Pierre Ossmanca0c5f52017-09-15 15:40:47 +0200105 pthread_cond_destroy((pthread_cond_t*)systemCondition);
Pierre Ossman687d52c2015-11-12 12:16:08 +0100106 delete (pthread_cond_t*)systemCondition;
Pierre Ossman687d52c2015-11-12 12:16:08 +0100107#endif
108}
109
110void Condition::wait()
111{
112#ifdef WIN32
113 BOOL ret;
114
115 ret = SleepConditionVariableCS((CONDITION_VARIABLE*)systemCondition,
116 (CRITICAL_SECTION*)mutex->systemMutex,
117 INFINITE);
118 if (!ret)
119 throw rdr::SystemException("Failed to wait on condition variable", GetLastError());
120#else
121 int ret;
122
123 ret = pthread_cond_wait((pthread_cond_t*)systemCondition,
124 (pthread_mutex_t*)mutex->systemMutex);
125 if (ret != 0)
126 throw rdr::SystemException("Failed to wait on condition variable", ret);
127#endif
128}
129
130void Condition::signal()
131{
132#ifdef WIN32
133 WakeConditionVariable((CONDITION_VARIABLE*)systemCondition);
134#else
135 int ret;
136
137 ret = pthread_cond_signal((pthread_cond_t*)systemCondition);
138 if (ret != 0)
139 throw rdr::SystemException("Failed to signal condition variable", ret);
140#endif
141}
142
143void Condition::broadcast()
144{
145#ifdef WIN32
146 WakeAllConditionVariable((CONDITION_VARIABLE*)systemCondition);
147#else
148 int ret;
149
150 ret = pthread_cond_broadcast((pthread_cond_t*)systemCondition);
151 if (ret != 0)
152 throw rdr::SystemException("Failed to broadcast condition variable", ret);
153#endif
154}