Asterisk - The Open Source Telephony Project  18.5.0
sem.h
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 #ifndef ASTERISK_SEMAPHORE_H
20 #define ASTERISK_SEMAPHORE_H
21 
22 /*!
23  * \file
24  *
25  * \brief Asterisk semaphore API
26  *
27  * This API is a thin wrapper around the POSIX semaphore API (when available),
28  * so see the POSIX documentation for further details.
29  */
30 
31 #ifdef HAS_WORKING_SEMAPHORE
32 /* Working semaphore implementation detected */
33 
34 #include <semaphore.h>
35 
36 struct ast_sem {
37  sem_t real_sem;
38 };
39 
40 #define AST_SEM_VALUE_MAX SEM_VALUE_MAX
41 
42 /* These are thin wrappers; might as well inline them */
43 
44 static force_inline int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
45 {
46  return sem_init(&sem->real_sem, pshared, value);
47 }
48 
49 static force_inline int ast_sem_destroy(struct ast_sem *sem)
50 {
51  return sem_destroy(&sem->real_sem);
52 }
53 
54 static force_inline int ast_sem_post(struct ast_sem *sem)
55 {
56  return sem_post(&sem->real_sem);
57 }
58 
59 static force_inline int ast_sem_wait(struct ast_sem *sem)
60 {
61  return sem_wait(&sem->real_sem);
62 }
63 
64 static force_inline int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout)
65 {
66  return sem_timedwait(&sem->real_sem, abs_timeout);
67 }
68 
69 static force_inline int ast_sem_getvalue(struct ast_sem *sem, int *sval)
70 {
71  return sem_getvalue(&sem->real_sem, sval);
72 }
73 
74 #else
75 /* Unnamed semaphores don't work. Rolling our own, I guess... */
76 
77 #include "asterisk/lock.h"
78 
79 #include <limits.h>
80 
81 struct ast_sem {
82  /*! Current count of this semaphore */
83  int count;
84  /*! Number of threads currently waiting for this semaphore */
85  int waiters;
86  /*! Mutual exclusion */
88  /*! Condition for singalling waiters */
90 };
91 
92 #define AST_SEM_VALUE_MAX INT_MAX
93 
94 /*!
95  * \brief Initialize a semaphore.
96  *
97  * \param sem Semaphore to initialize.
98  * \param pshared Pass true (nonzero) to share this thread between processes.
99  * Not be supported on all platforms, so be wary!
100  * But leave the parameter, to be compatible with the POSIX ABI
101  * in case we need to add support in the future.
102  * \param value Initial value of the semaphore.
103  *
104  * \return 0 on success.
105  * \return -1 on error, errno set to indicate error.
106  */
107 int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value);
108 
109 /*!
110  * \brief Destroy a semaphore.
111  *
112  * Destroying a semaphore that other threads are currently blocked on produces
113  * undefined behavior.
114  *
115  * \param sem Semaphore to destroy.
116  *
117  * \return 0 on success.
118  * \return -1 on error, errno set to indicate error.
119  */
120 int ast_sem_destroy(struct ast_sem *sem);
121 
122 /*!
123  * \brief Increments the semaphore, unblocking a waiter if necessary.
124  *
125  * \param sem Semaphore to increment.
126  *
127  * \return 0 on success.
128  * \return -1 on error, errno set to indicate error.
129  */
130 int ast_sem_post(struct ast_sem *sem);
131 
132 /*!
133  * \brief Decrements the semaphore.
134  *
135  * If the semaphore's current value is zero, this function blocks until another
136  * thread posts (ast_sem_post()) to the semaphore (or is interrupted by a signal
137  * handler, which sets errno to EINTR).
138  *
139  * \param sem Semaphore to decrement.
140  *
141  * \return 0 on success.
142  * \return -1 on error, errno set to indicate error.
143  */
144 int ast_sem_wait(struct ast_sem *sem);
145 
146 /*!
147  * \brief Decrements the semaphore, waiting until abs_timeout.
148  *
149  * If the semaphore's current value is zero, this function blocks until another
150  * thread posts (ast_sem_post()) to the semaphore (or is interrupted by a signal
151  * handler, which sets errno to EINTR).
152  *
153  * \param sem Semaphore to decrement.
154  *
155  * \return 0 on success.
156  * \return -1 on error, errno set to indicate error.
157  */
158 int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout);
159 
160 /*!
161  * \brief Gets the current value of the semaphore.
162  *
163  * If threads are blocked on this semaphore, POSIX allows the return value to be
164  * either 0 or a negative number whose absolute value is the number of threads
165  * blocked. Don't assume that it will give you one or the other; Asterisk has
166  * been ported to just about everything.
167  *
168  * \param sem Semaphore to query.
169  * \param[out] sval Output value.
170  *
171  * \return 0 on success.
172  * \return -1 on error, errno set to indicate error.
173  */
174 int ast_sem_getvalue(struct ast_sem *sem, int *sval);
175 
176 #endif
177 
178 #endif /* ASTERISK_SEMAPHORE_H */
Asterisk locking-related definitions:
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
int waiters
Definition: sem.h:85
ast_mutex_t mutex
Definition: sem.h:87
#define force_inline
Definition: compiler.h:29
int ast_sem_post(struct ast_sem *sem)
Increments the semaphore, unblocking a waiter if necessary.
int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout)
Decrements the semaphore, waiting until abs_timeout.
int value
Definition: syslog.c:37
pthread_cond_t ast_cond_t
Definition: lock.h:176
int ast_sem_getvalue(struct ast_sem *sem, int *sval)
Gets the current value of the semaphore.
int ast_sem_wait(struct ast_sem *sem)
Decrements the semaphore.
int count
Definition: sem.h:83
ast_cond_t cond
Definition: sem.h:89
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
Initialize a semaphore.
Definition: sem.h:81
Structure for mutex and tracking information.
Definition: lock.h:135