2 * Copyright (c) 2005 Zmanda, Inc. All Rights Reserved.
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 2.1 as
6 * published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11 * License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
18 * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
21 /* GLib does not provide semaphores, which are useful in queue.c.
22 So, we implement it here. */
24 #include "semaphore.h"
27 semaphore_t* semaphore_new_with_value(int value) {
30 if (!g_thread_supported())
33 rval = malloc(sizeof(*rval));
35 rval->mutex = g_mutex_new();
36 rval->decrement_cond = g_cond_new();
37 rval->zero_cond = g_cond_new();
39 if (rval->mutex == NULL || rval->decrement_cond == NULL ||
40 rval->zero_cond == NULL) {
48 void semaphore_free(semaphore_t* o) {
49 g_mutex_free(o->mutex);
50 g_cond_free(o->decrement_cond);
51 g_cond_free(o->zero_cond);
55 /* This function checks if the semaphore would is zero or negative.
56 * If so, the zero_cond is signalled. We assume that the mutex is
58 static void check_empty(semaphore_t * o) {
60 g_cond_broadcast(o->zero_cond);
64 void semaphore_increment(semaphore_t* o, unsigned int inc) {
65 g_return_if_fail(o != NULL);
66 g_return_if_fail(inc != 0);
68 semaphore_force_adjust(o, inc);
71 void semaphore_decrement(semaphore_t* o, unsigned int dec) {
73 g_return_if_fail(o != NULL);
75 g_return_if_fail(sdec >= 0);
77 g_mutex_lock(o->mutex);
78 while (o->value < sdec) {
79 g_cond_wait(o->decrement_cond, o->mutex);
83 g_mutex_unlock(o->mutex);
86 void semaphore_force_adjust(semaphore_t* o, int inc) {
87 g_return_if_fail(o != NULL);
89 g_mutex_lock(o->mutex);
94 g_cond_broadcast(o->decrement_cond);
95 g_mutex_unlock(o->mutex);
99 void semaphore_force_set(semaphore_t* o, int value) {
101 g_return_if_fail(o != NULL);
103 g_mutex_lock(o->mutex);
106 if (value < oldvalue)
109 g_cond_broadcast(o->decrement_cond);
110 g_mutex_unlock(o->mutex);
114 void semaphore_wait_empty(semaphore_t * o) {
115 g_return_if_fail(o != NULL);
117 g_mutex_lock(o->mutex);
118 while (o->value > 0) {
119 g_cond_wait(o->zero_cond, o->mutex);
121 g_mutex_unlock(o->mutex);