summaryrefslogtreecommitdiff
path: root/include/asterisk/sem.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asterisk/sem.h')
-rw-r--r--include/asterisk/sem.h157
1 files changed, 157 insertions, 0 deletions
diff --git a/include/asterisk/sem.h b/include/asterisk/sem.h
new file mode 100644
index 000000000..8f6356c01
--- /dev/null
+++ b/include/asterisk/sem.h
@@ -0,0 +1,157 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * David M. Lee, II <dlee@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef ASTERISK_SEMAPHORE_H
+#define ASTERISK_SEMAPHORE_H
+
+/*!
+ * \file Asterisk semaphore API
+ *
+ * This API is a thin wrapper around the POSIX semaphore API (when available),
+ * so see the POSIX documentation for further details.
+ */
+
+#ifdef HAS_WORKING_SEMAPHORE
+/* Working semaphore implementation detected */
+
+#include <semaphore.h>
+
+struct ast_sem {
+ sem_t real_sem;
+};
+
+#define AST_SEM_VALUE_MAX SEM_VALUE_MAX
+
+/* These are thin wrappers; might as well inline them */
+
+static force_inline int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
+{
+ return sem_init(&sem->real_sem, pshared, value);
+}
+
+static force_inline int ast_sem_destroy(struct ast_sem *sem)
+{
+ return sem_destroy(&sem->real_sem);
+}
+
+static force_inline int ast_sem_post(struct ast_sem *sem)
+{
+ return sem_post(&sem->real_sem);
+}
+
+static force_inline int ast_sem_wait(struct ast_sem *sem)
+{
+ return sem_wait(&sem->real_sem);
+}
+
+static force_inline int ast_sem_getvalue(struct ast_sem *sem, int *sval)
+{
+ return sem_getvalue(&sem->real_sem, sval);
+}
+
+#else
+/* Unnamed semaphores don't work. Rolling our own, I guess... */
+
+#include "asterisk/lock.h"
+
+#include <limits.h>
+
+struct ast_sem {
+ /*! Current count of this semaphore */
+ int count;
+ /*! Number of threads currently waiting for this semaphore */
+ int waiters;
+ /*! Mutual exclusion */
+ ast_mutex_t mutex;
+ /*! Condition for singalling waiters */
+ ast_cond_t cond;
+};
+
+#define AST_SEM_VALUE_MAX INT_MAX
+
+/*!
+ * \brief Initialize a semaphore.
+ *
+ * \param sem Semaphore to initialize.
+ * \param pshared Pass true (nonzero) to share this thread between processes.
+ * Not be supported on all platforms, so be wary!
+ * But leave the parameter, to be compatible with the POSIX ABI
+ * in case we need to add support in the future.
+ * \param value Initial value of the semaphore.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
+int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value);
+
+/*!
+ * \brief Destroy a semaphore.
+ *
+ * Destroying a semaphore that other threads are currently blocked on produces
+ * undefined behavior.
+ *
+ * \param sem Semaphore to destroy.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
+int ast_sem_destroy(struct ast_sem *sem);
+
+/*!
+ * \brief Increments the semaphore, unblocking a waiter if necessary.
+ *
+ * \param sem Semaphore to increment.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
+int ast_sem_post(struct ast_sem *sem);
+
+/*!
+ * \brief Decrements the semaphore.
+ *
+ * If the semaphore's current value is zero, this function blocks until another
+ * thread posts (ast_sem_post()) to the semaphore (or is interrupted by a signal
+ * handler, which sets errno to EINTR).
+ *
+ * \param sem Semaphore to decrement.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
+int ast_sem_wait(struct ast_sem *sem);
+
+/*!
+ * \brief Gets the current value of the semaphore.
+ *
+ * If threads are blocked on this semaphore, POSIX allows the return value to be
+ * either 0 or a negative number whose absolute value is the number of threads
+ * blocked. Don't assume that it will give you one or the other; Asterisk has
+ * been ported to just about everything.
+ *
+ * \param sem Semaphore to query.
+ * \param[out] sval Output value.
+ *
+ * \return 0 on success.
+ * \return -1 on error, errno set to indicate error.
+ */
+int ast_sem_getvalue(struct ast_sem *sem, int *sval);
+
+#endif
+
+#endif /* ASTERISK_SEMAPHORE_H */