1
/*
2
 * Copyright (C) 2009-2010 Felipe Contreras
3
 *
4
 * Author: Felipe Contreras <felipe.contreras@gmail.com>
5
 *
6
 * This file may be used under the terms of the GNU Lesser General Public
7
 * License version 2.1, a copy of which is found in LICENSE included in the
8
 * packaging of this file.
9
 */
10
11
#ifndef SEM_H
12
#define SEM_H
13
14
#include <glib.h>
15
16
typedef struct GSem GSem;
17
18
struct GSem {
19
	GCond *condition;
20
	GMutex *mutex;
21
	guint count;
22
};
23
24
static inline GSem *
25
g_sem_new(guint count)
26
{
27
	GSem *sem;
28
29
	sem = g_new(GSem, 1);
30
	sem->condition = g_cond_new();
31
	sem->mutex = g_mutex_new();
32
	sem->count = count;
33
34
	return sem;
35
}
36
37
static inline void
38
g_sem_free(GSem *sem)
39
{
40
	g_cond_free(sem->condition);
41
	g_mutex_free(sem->mutex);
42
	g_free(sem);
43
}
44
45
static inline void
46
g_sem_down(GSem *sem)
47
{
48
	g_mutex_lock(sem->mutex);
49
	while (sem->count == 0)
50
		g_cond_wait(sem->condition, sem->mutex);
51
	sem->count--;
52
	g_mutex_unlock(sem->mutex);
53
}
54
55
static inline bool
56
g_sem_down_timed(GSem *sem, int seconds)
57
{
58
	GTimeVal tv;
59
60
	g_mutex_lock(sem->mutex);
61
	while (sem->count == 0) {
62
		g_get_current_time(&tv);
63
		tv.tv_sec += seconds;
64
		if (!g_cond_timed_wait(sem->condition, sem->mutex, &tv)) {
65
			g_mutex_unlock(sem->mutex);
66
			return false;
67
		}
68
	}
69
	sem->count--;
70
	g_mutex_unlock(sem->mutex);
71
72
	return true;
73
}
74
75
static inline void
76
g_sem_up(GSem *sem)
77
{
78
	g_mutex_lock(sem->mutex);
79
	sem->count++;
80
	g_cond_signal(sem->condition);
81
	g_mutex_unlock(sem->mutex);
82
}
83
84
#endif /* SEM_H */