Asterisk - The Open Source Telephony Project GIT-master-a358458
sem.c
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 <dlee@digium.com>
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/*! \file
20 *
21 * \brief Asterisk semaphore support.
22 */
23
24#include "asterisk.h"
25
26#include "asterisk/sem.h"
27#include "asterisk/utils.h"
28
29#ifndef HAS_WORKING_SEMAPHORE
30
31/* DIY semaphores! */
32
33int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
34{
35 if (pshared) {
36 /* Don't need it... yet */
37 errno = ENOSYS;
38 return -1;
39 }
40
41 /* Since value is unsigned, this will also catch attempts to init with
42 * a negative value */
44 errno = EINVAL;
45 return -1;
46 }
47
48 sem->count = value;
49 sem->waiters = 0;
50 ast_mutex_init(&sem->mutex);
51 ast_cond_init(&sem->cond, NULL);
52 return 0;
53}
54
55int ast_sem_destroy(struct ast_sem *sem)
56{
59 return 0;
60}
61
62int ast_sem_post(struct ast_sem *sem)
63{
64 SCOPED_MUTEX(lock, &sem->mutex);
65
66 ast_assert(sem->count >= 0);
67
68 if (sem->count == AST_SEM_VALUE_MAX) {
69 errno = EOVERFLOW;
70 return -1;
71 }
72
73 /* Give it up! */
74 ++sem->count;
75
76 /* Release a waiter, if needed */
77 if (sem->waiters) {
78 ast_cond_signal(&sem->cond);
79 }
80
81 return 0;
82}
83
84int ast_sem_wait(struct ast_sem *sem)
85{
86 int res;
87 SCOPED_MUTEX(lock, &sem->mutex);
88
89 ast_assert(sem->count >= 0);
90
91 /* Wait for a non-zero count */
92 ++sem->waiters;
93 while (sem->count == 0) {
94 res = ast_cond_wait(&sem->cond, &sem->mutex);
95 /* Give up on error */
96 if (res != 0) {
97 --sem->waiters;
98 return res;
99 }
100 }
101 --sem->waiters;
102
103 /* Take it! */
104 --sem->count;
105
106 return 0;
107}
108
109int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout)
110{
111 int res;
112 SCOPED_MUTEX(lock, &sem->mutex);
113
114 ast_assert(sem->count >= 0);
115
116 /* Wait for a non-zero count */
117 ++sem->waiters;
118 while (sem->count == 0) {
119 res = ast_cond_timedwait(&sem->cond, &sem->mutex, abs_timeout);
120 /* Give up on error */
121 if (res != 0) {
122 --sem->waiters;
123 return res;
124 }
125 }
126 --sem->waiters;
127
128 /* Take it! */
129 --sem->count;
130
131 return 0;
132}
133
134int ast_sem_getvalue(struct ast_sem *sem, int *sval)
135{
136 SCOPED_MUTEX(lock, &sem->mutex);
137
138 ast_assert(sem->count >= 0);
139
140 *sval = sem->count;
141
142 return 0;
143}
144
145#endif
ast_mutex_t lock
Definition: app_sla.c:331
Asterisk main include file. File version handling, generic pbx functions.
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:589
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_cond_signal(cond)
Definition: lock.h:203
int errno
#define NULL
Definition: resample.c:96
Asterisk semaphore API.
int ast_sem_getvalue(struct ast_sem *sem, int *sval)
Gets the current value of the semaphore.
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
Initialize a semaphore.
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
#define AST_SEM_VALUE_MAX
Definition: sem.h:92
int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout)
Decrements the semaphore, waiting until abs_timeout.
int ast_sem_wait(struct ast_sem *sem)
Decrements the semaphore.
int ast_sem_post(struct ast_sem *sem)
Increments the semaphore, unblocking a waiter if necessary.
Definition: sem.h:81
ast_cond_t cond
Definition: sem.h:89
ast_mutex_t mutex
Definition: sem.h:87
int waiters
Definition: sem.h:85
int count
Definition: sem.h:83
int value
Definition: syslog.c:37
Utility functions.
#define ast_assert(a)
Definition: utils.h:739