Asterisk - The Open Source Telephony Project  18.5.0
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 <[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 /*! \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 
33 int 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 */
43  if (value > AST_SEM_VALUE_MAX) {
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 
55 int ast_sem_destroy(struct ast_sem *sem)
56 {
57  ast_mutex_destroy(&sem->mutex);
58  ast_cond_destroy(&sem->cond);
59  return 0;
60 }
61 
62 int 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 
84 int 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 
109 int 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 
134 int 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
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
Asterisk main include file. File version handling, generic pbx functions.
int waiters
Definition: sem.h:85
ast_mutex_t mutex
Definition: sem.h:87
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.
#define AST_SEM_VALUE_MAX
Definition: sem.h:92
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_cond_signal(cond)
Definition: lock.h:201
Utility functions.
Asterisk semaphore API.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
ast_mutex_t lock
Definition: app_meetme.c:1091
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
int errno
#define ast_cond_destroy(cond)
Definition: lock.h:200
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
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204