]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/unix_semaphore.cc
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 - 2005 PowerDNS.COM BV
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation
9 Additionally, the license of this program contains a special
10 exception which allows to distribute the program in binary form when
11 it is linked against OpenSSL.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "pdnsexception.hh"
37 #include <sys/types.h>
40 #if defined(_AIX) || defined(__APPLE__)
42 // Darwin 6.0 Compatible implementation, uses pthreads so it portable across more platforms.
44 #define SEM_VALUE_MAX 32767
45 #define SEM_MAGIC ((uint32_t) 0x09fa4012)
47 Semaphore::Semaphore(unsigned int value
)
49 if (value
> SEM_VALUE_MAX
) {
50 throw PDNSException("Cannot create semaphore: value too large");
55 if (pthread_mutex_init(&m_lock
, NULL
) != 0) {
56 throw PDNSException("Cannot create semaphore: cannot allocate mutex");
59 if (pthread_cond_init(&m_gtzero
, NULL
) != 0) {
60 pthread_mutex_destroy(&m_lock
);
61 throw PDNSException("Cannot create semaphore: cannot allocate condition");
64 m_count
= (uint32_t) value
;
71 pthread_mutex_lock(&m_lock
);
75 pthread_cond_signal(&m_gtzero
);
78 pthread_mutex_unlock(&m_lock
);
85 pthread_mutex_lock(&m_lock
);
87 while (m_count
== 0) {
89 pthread_cond_wait(&m_gtzero
, &m_lock
);
95 pthread_mutex_unlock(&m_lock
);
100 int Semaphore::tryWait()
104 pthread_mutex_lock(&m_lock
);
113 pthread_mutex_unlock(&m_lock
);
118 int Semaphore::getValue(Semaphore::sem_value_t
*sval
)
120 pthread_mutex_lock(&m_lock
);
122 pthread_mutex_unlock(&m_lock
);
127 Semaphore::~Semaphore()
129 // Make sure there are no waiters.
131 pthread_mutex_lock(&m_lock
);
132 if (m_nwaiters
> 0) {
133 pthread_mutex_unlock(&m_lock
);
137 pthread_mutex_unlock(&m_lock
);
141 pthread_mutex_destroy(&m_lock
);
142 pthread_cond_destroy(&m_gtzero
);
148 #else /* not DARWIN from here on */
151 Semaphore::Semaphore(unsigned int value
)
153 m_pSemaphore
=new sem_t
;
154 if (sem_init(m_pSemaphore
, 0, value
) == -1) {
155 theL() << Logger::Error
<< "Cannot create semaphore: " << stringerror() << endl
;
160 int Semaphore::post()
162 return sem_post(m_pSemaphore
);
165 int Semaphore::wait()
169 ret
= sem_wait(m_pSemaphore
);
170 while (ret
== -1 && errno
== EINTR
);
173 int Semaphore::tryWait()
175 return sem_trywait(m_pSemaphore
);
178 int Semaphore::getValue(Semaphore::sem_value_t
*sval
)
180 return sem_getvalue(m_pSemaphore
, sval
);
183 Semaphore::~Semaphore()