]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/unix_semaphore.cc
5257d861a6cabe2c3443013c1259889708b2cf11
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
30 #include "pdnsexception.hh"
35 #include <sys/types.h>
38 #if defined(_AIX) || defined(__APPLE__)
40 // Darwin 6.0 Compatible implementation, uses pthreads so it portable across more platforms.
42 #define SEM_VALUE_MAX 32767
43 #define SEM_MAGIC ((uint32_t) 0x09fa4012)
45 Semaphore::Semaphore(unsigned int value
)
47 if (value
> SEM_VALUE_MAX
) {
48 throw PDNSException("Cannot create semaphore: value too large");
53 if (pthread_mutex_init(&m_lock
, NULL
) != 0) {
54 throw PDNSException("Cannot create semaphore: cannot allocate mutex");
57 if (pthread_cond_init(&m_gtzero
, NULL
) != 0) {
58 pthread_mutex_destroy(&m_lock
);
59 throw PDNSException("Cannot create semaphore: cannot allocate condition");
62 m_count
= (uint32_t) value
;
69 pthread_mutex_lock(&m_lock
);
73 pthread_cond_signal(&m_gtzero
);
76 pthread_mutex_unlock(&m_lock
);
83 pthread_mutex_lock(&m_lock
);
85 while (m_count
== 0) {
87 pthread_cond_wait(&m_gtzero
, &m_lock
);
93 pthread_mutex_unlock(&m_lock
);
98 int Semaphore::tryWait()
102 pthread_mutex_lock(&m_lock
);
111 pthread_mutex_unlock(&m_lock
);
116 int Semaphore::getValue(Semaphore::sem_value_t
*sval
)
118 pthread_mutex_lock(&m_lock
);
120 pthread_mutex_unlock(&m_lock
);
125 Semaphore::~Semaphore()
127 // Make sure there are no waiters.
129 pthread_mutex_lock(&m_lock
);
130 if (m_nwaiters
> 0) {
131 pthread_mutex_unlock(&m_lock
);
135 pthread_mutex_unlock(&m_lock
);
139 pthread_mutex_destroy(&m_lock
);
140 pthread_cond_destroy(&m_gtzero
);
146 #else /* not DARWIN from here on */
149 Semaphore::Semaphore(unsigned int value
)
151 m_pSemaphore
=new sem_t
;
152 if (sem_init(m_pSemaphore
, 0, value
) == -1) {
153 theL() << Logger::Error
<< "Cannot create semaphore: " << stringerror() << endl
;
158 int Semaphore::post()
160 return sem_post(m_pSemaphore
);
163 int Semaphore::wait()
167 ret
= sem_wait(m_pSemaphore
);
168 while (ret
== -1 && errno
== EINTR
);
171 int Semaphore::tryWait()
173 return sem_trywait(m_pSemaphore
);
176 int Semaphore::getValue(Semaphore::sem_value_t
*sval
)
178 return sem_getvalue(m_pSemaphore
, sval
);
181 Semaphore::~Semaphore()