Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / libedataserver / e-flag.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* 
3  * Copyright (C) 2007 Novell, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU Lesser General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "e-flag.h"
21
22 struct _EFlag {
23         GCond *cond;
24         GMutex *mutex;
25         gboolean is_set;
26 };
27
28 /**
29  * e_flag_new:
30  *
31  * Creates a new #EFlag object.  It is initially unset.
32  *
33  * Returns: a new #EFlag
34  **/
35 EFlag *
36 e_flag_new (void)
37 {
38         EFlag *flag;
39
40         flag = g_slice_new (EFlag);
41         flag->cond = g_cond_new ();
42         flag->mutex = g_mutex_new ();
43         flag->is_set = FALSE;
44
45         return flag;
46 }
47
48 /**
49  * e_flag_is_set:
50  * @flag: an #EFlag
51  *
52  * Returns the state of @flag.
53  *
54  * Returns: %TRUE if @flag is set
55  **/
56 gboolean
57 e_flag_is_set (EFlag *flag)
58 {
59         gboolean is_set;
60
61         g_return_val_if_fail (flag != NULL, FALSE);
62
63         g_mutex_lock (flag->mutex);
64         is_set = flag->is_set;
65         g_mutex_unlock (flag->mutex);
66
67         return is_set;
68 }
69
70 /**
71  * e_flag_set:
72  * @flag: an #EFlag
73  *
74  * Sets @flag.  All threads waiting on @flag are woken up.  Threads that
75  * call e_flag_wait() or e_flag_timed_wait() once @flag is set will not
76  * block at all.
77  **/
78 void
79 e_flag_set (EFlag *flag)
80 {
81         g_return_if_fail (flag != NULL);
82
83         g_mutex_lock (flag->mutex);
84         flag->is_set = TRUE;
85         g_cond_broadcast (flag->cond);
86         g_mutex_unlock (flag->mutex);
87 }
88
89 /**
90  * e_flag_clear:
91  * @flag: an #EFlag
92  *
93  * Unsets @flag.  Subsequent calls to e_flag_wait() or e_flag_timed_wait()
94  * will block until @flag is set.
95  **/
96 void
97 e_flag_clear (EFlag *flag)
98 {
99         g_return_if_fail (flag != NULL);
100
101         g_mutex_lock (flag->mutex);
102         flag->is_set = FALSE;
103         g_mutex_unlock (flag->mutex);
104 }
105
106 /**
107  * e_flag_wait:
108  * @flag: an #EFlag
109  *
110  * Blocks until @flag is set.  If @flag is already set, the function returns
111  * immediately.
112  **/
113 void
114 e_flag_wait (EFlag *flag)
115 {
116         g_return_if_fail (flag != NULL);
117
118         g_mutex_lock (flag->mutex);
119         while (!flag->is_set)
120                 g_cond_wait (flag->cond, flag->mutex);
121         g_mutex_unlock (flag->mutex);
122 }
123
124 /**
125  * e_flag_timed_wait:
126  * @flag: an #EFlag
127  * @abs_time: a #GTimeVal, determining the final time
128  *
129  * Blocks until @flag is set, or until the time specified by @abs_time.
130  * If @flag is already set, the function returns immediately.  The return
131  * value indicates the state of @flag after waiting.
132  *
133  * If @abs_time is %NULL, e_flag_timed_wait() acts like e_flag_wait().
134  *
135  * To easily calculate @abs_time, a combination of g_get_current_time() and
136  * g_time_val_add() can be used.
137  *
138  * Returns: %TRUE if @flag is now set
139  **/
140 gboolean
141 e_flag_timed_wait (EFlag *flag, GTimeVal *abs_time)
142 {
143         gboolean is_set;
144
145         g_return_val_if_fail (flag != NULL, FALSE);
146
147         g_mutex_lock (flag->mutex);
148         while (!flag->is_set)
149                 if (!g_cond_timed_wait (flag->cond, flag->mutex, abs_time))
150                         break;
151         is_set = flag->is_set;
152         g_mutex_unlock (flag->mutex);
153
154         return is_set;
155 }
156
157 /**
158  * e_flag_free:
159  * @flag: an #EFlag
160  *
161  * Destroys @flag.
162  **/
163 void
164 e_flag_free (EFlag *flag)
165 {
166         g_return_if_fail (flag != NULL);
167
168         g_cond_free (flag->cond);
169         g_mutex_free (flag->mutex);
170         g_slice_free (EFlag, flag);
171 }