aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/mhd_sem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/mhd_sem.c')
-rw-r--r--src/microhttpd/mhd_sem.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/microhttpd/mhd_sem.c b/src/microhttpd/mhd_sem.c
new file mode 100644
index 00000000..fdd5dbe4
--- /dev/null
+++ b/src/microhttpd/mhd_sem.c
@@ -0,0 +1,138 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2016 Christian Grothoff
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19*/
20
21/**
22 * @file microhttpd/mhd_sem.c
23 * @brief implementation of semaphores
24 * @author Christian Grothoff
25 */
26#include "internal.h"
27#include "mhd_locks.h"
28
29/**
30 * A semaphore.
31 */
32struct MHD_Semaphore
33{
34 /**
35 * Mutex we use internally.
36 */
37 pthread_mutex_t mutex;
38
39 /**
40 * Condition variable used to implement the semaphore.
41 */
42 pthread_cond_t cv;
43
44 /**
45 * Current value of the semaphore.
46 */
47 unsigned int counter;
48};
49
50
51/**
52 * Create a semaphore with an initial counter of @a init
53 *
54 * @param init initial counter
55 * @return the semaphore, NULL on error
56 */
57struct MHD_Semaphore *
58MHD_semaphore_create (unsigned int init)
59{
60 struct MHD_Semaphore *sem;
61
62 sem = malloc (sizeof (struct MHD_Semaphore));
63 if (NULL == sem)
64 return NULL;
65 sem->counter = init;
66 if (0 != pthread_mutex_init (&sem->mutex,
67 NULL))
68 {
69 free (sem);
70 return NULL;
71 }
72 if (0 != pthread_cond_init (&sem->cv,
73 NULL))
74 {
75 (void) pthread_mutex_destroy (&sem->mutex);
76 free (sem);
77 return NULL;
78 }
79 return sem;
80}
81
82
83/**
84 * Count down the semaphore, block if necessary.
85 *
86 * @param sem semaphore to count down.
87 */
88void
89MHD_semaphore_down (struct MHD_Semaphore *sem)
90{
91 if (! pthread_mutex_lock (&sem->mutex))
92 MHD_PANIC ("pthread_mutex_lock for semaphore failed\n");
93 while (0 == sem->counter)
94 {
95 if (0 != pthread_cond_wait (&sem->cv,
96 &sem->mutex))
97 MHD_PANIC ("pthread_cond_wait failed\n");
98 }
99 sem->counter--;
100 if (! pthread_mutex_unlock (&sem->mutex))
101 MHD_PANIC ("pthread_mutex_unlock for semaphore failed\n");
102}
103
104
105/**
106 * Increment the semaphore.
107 *
108 * @param sem semaphore to increment.
109 */
110void
111MHD_semaphore_up (struct MHD_Semaphore *sem)
112{
113 if (! pthread_mutex_lock (&sem->mutex))
114 MHD_PANIC ("pthread_mutex_lock for semaphore failed\n");
115 sem->counter++;
116 pthread_cond_signal (&sem->cv);
117 if (! pthread_mutex_unlock (&sem->mutex))
118 MHD_PANIC ("pthread_mutex_unlock for semaphore failed\n");
119}
120
121
122/**
123 * Destroys the semaphore.
124 *
125 * @param sem semaphore to destroy.
126 */
127void
128MHD_semaphore_destroy (struct MHD_Semaphore *sem)
129{
130 if (0 != pthread_cond_destroy (&sem->cv))
131 MHD_PANIC ("pthread_cond_destroy failed\n");
132 if (0 != pthread_mutex_destroy (&sem->mutex))
133 MHD_PANIC ("pthread_mutex_destroy failed\n");
134 free (sem);
135}
136
137
138/* end of mhd_sem.c */