]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/unix_semaphore.cc
Merge pull request #7692 from rgacogne/dnsdist-boost-170-badsig
[thirdparty/pdns.git] / pdns / unix_semaphore.cc
CommitLineData
b16edb03 1/*
6edbf68a
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
b16edb03
BH
25#include "utility.hh"
26#include <cstring>
27#include <fcntl.h>
28#include <unistd.h>
29#include <stdlib.h>
5c409fa2 30#include "pdnsexception.hh"
b16edb03
BH
31#include "logger.hh"
32#include "misc.hh"
33#include <pwd.h>
34#include <grp.h>
35#include <sys/types.h>
36
37
82442a51 38#if defined(_AIX) || defined(__APPLE__)
b16edb03
BH
39
40// Darwin 6.0 Compatible implementation, uses pthreads so it portable across more platforms.
41
42#define SEM_VALUE_MAX 32767
092f210a 43#define SEM_MAGIC ((uint32_t) 0x09fa4012)
b16edb03
BH
44
45Semaphore::Semaphore(unsigned int value)
46{
47 if (value > SEM_VALUE_MAX) {
3f81d239 48 throw PDNSException("Cannot create semaphore: value too large");
b16edb03
BH
49 }
50
51 // Initialize
52
53 if (pthread_mutex_init(&m_lock, NULL) != 0) {
3f81d239 54 throw PDNSException("Cannot create semaphore: cannot allocate mutex");
b16edb03
BH
55 }
56
57 if (pthread_cond_init(&m_gtzero, NULL) != 0) {
58 pthread_mutex_destroy(&m_lock);
3f81d239 59 throw PDNSException("Cannot create semaphore: cannot allocate condition");
b16edb03
BH
60 }
61
092f210a 62 m_count = (uint32_t) value;
b16edb03
BH
63 m_nwaiters = 0;
64 m_magic = SEM_MAGIC;
65}
66
67int Semaphore::post()
68{
69 pthread_mutex_lock(&m_lock);
70
71 m_count++;
72 if (m_nwaiters > 0) {
73 pthread_cond_signal(&m_gtzero);
74 }
75
76 pthread_mutex_unlock(&m_lock);
77
78 return 0;
79}
80
81int Semaphore::wait()
82{
83 pthread_mutex_lock(&m_lock);
84
85 while (m_count == 0) {
86 m_nwaiters++;
87 pthread_cond_wait(&m_gtzero, &m_lock);
88 m_nwaiters--;
89 }
90
91 m_count--;
92
93 pthread_mutex_unlock(&m_lock);
94
95 return 0;
96}
97
98int Semaphore::tryWait()
99{
100 int retval = 0;
101
102 pthread_mutex_lock(&m_lock);
103
104 if (m_count > 0) {
105 m_count--;
106 } else {
107 errno = EAGAIN;
108 retval = -1;
109 }
110
111 pthread_mutex_unlock(&m_lock);
112
113 return retval;
114}
115
116int Semaphore::getValue(Semaphore::sem_value_t *sval)
117{
118 pthread_mutex_lock(&m_lock);
119 *sval = m_count;
120 pthread_mutex_unlock(&m_lock);
121
122 return 0;
123}
124
125Semaphore::~Semaphore()
126{
127 // Make sure there are no waiters.
128
129 pthread_mutex_lock(&m_lock);
130 if (m_nwaiters > 0) {
131 pthread_mutex_unlock(&m_lock);
132 //errno = EBUSY;
133 //return -1;
134 }
135 pthread_mutex_unlock(&m_lock);
136
137 // Destroy it.
138
139 pthread_mutex_destroy(&m_lock);
140 pthread_cond_destroy(&m_gtzero);
141 m_magic = 0;
142
143 //return 0;
144}
145
146#else /* not DARWIN from here on */
147
148
149Semaphore::Semaphore(unsigned int value)
150{
151 m_pSemaphore=new sem_t;
152 if (sem_init(m_pSemaphore, 0, value) == -1) {
e6a9dde5 153 g_log << Logger::Error << "Cannot create semaphore: " << stringerror() << endl;
b16edb03
BH
154 exit(1);
155 }
156}
157
158int Semaphore::post()
159{
160 return sem_post(m_pSemaphore);
161}
162
163int Semaphore::wait()
164{
440191e1
BH
165 int ret;
166 do
167 ret = sem_wait(m_pSemaphore);
168 while (ret == -1 && errno == EINTR);
169 return ret;
b16edb03
BH
170}
171int Semaphore::tryWait()
172{
173 return sem_trywait(m_pSemaphore);
174}
175
176int Semaphore::getValue(Semaphore::sem_value_t *sval)
177{
178 return sem_getvalue(m_pSemaphore, sval);
179}
180
181Semaphore::~Semaphore()
182{
507039d0 183 delete m_pSemaphore;
b16edb03
BH
184}
185
186#endif