goa: Add missing linker flag (for real).
[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) 1999-2008 Novell, Inc. (www.novell.com)
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 /* This is to keep e_flag_timed_wait() building, since
29  * it relies on g_cond_timed_wait() which is deprecated. */
30 #if GLIB_CHECK_VERSION(2,35,6)
31 #ifdef G_DISABLE_DEPRECATED
32 gboolean        g_cond_timed_wait               (GCond *cond,
33                                                  GMutex *mutex,
34                                                  GTimeVal *timeval);
35 #endif /* G_DISABLE_DEPRECATED */
36 #endif /* GLIB_CHECK_VERSION */
37
38 /**
39  * e_flag_new:
40  *
41  * Creates a new #EFlag object.  It is initially unset.
42  *
43  * Returns: a new #EFlag
44  *
45  * Since: 1.12
46  **/
47 EFlag *
48 e_flag_new (void)
49 {
50         EFlag *flag;
51
52         flag = g_slice_new (EFlag);
53         g_cond_init (&flag->cond);
54         g_mutex_init (&flag->mutex);
55         flag->is_set = FALSE;
56
57         return flag;
58 }
59
60 /**
61  * e_flag_is_set:
62  * @flag: an #EFlag
63  *
64  * Returns the state of @flag.
65  *
66  * Returns: %TRUE if @flag is set
67  *
68  * Since: 1.12
69  **/
70 gboolean
71 e_flag_is_set (EFlag *flag)
72 {
73         gboolean is_set;
74
75         g_return_val_if_fail (flag != NULL, FALSE);
76
77         g_mutex_lock (&flag->mutex);
78         is_set = flag->is_set;
79         g_mutex_unlock (&flag->mutex);
80
81         return is_set;
82 }
83
84 /**
85  * e_flag_set:
86  * @flag: an #EFlag
87  *
88  * Sets @flag.  All threads waiting on @flag are woken up.  Threads that
89  * call e_flag_wait() or e_flag_wait_until() once @flag is set will not
90  * block at all.
91  *
92  * Since: 1.12
93  **/
94 void
95 e_flag_set (EFlag *flag)
96 {
97         g_return_if_fail (flag != NULL);
98
99         g_mutex_lock (&flag->mutex);
100         flag->is_set = TRUE;
101         g_cond_broadcast (&flag->cond);
102         g_mutex_unlock (&flag->mutex);
103 }
104
105 /**
106  * e_flag_clear:
107  * @flag: an #EFlag
108  *
109  * Unsets @flag.  Subsequent calls to e_flag_wait() or e_flag_wait_until()
110  * will block until @flag is set.
111  *
112  * Since: 1.12
113  **/
114 void
115 e_flag_clear (EFlag *flag)
116 {
117         g_return_if_fail (flag != NULL);
118
119         g_mutex_lock (&flag->mutex);
120         flag->is_set = FALSE;
121         g_mutex_unlock (&flag->mutex);
122 }
123
124 /**
125  * e_flag_wait:
126  * @flag: an #EFlag
127  *
128  * Blocks until @flag is set.  If @flag is already set, the function returns
129  * immediately.
130  *
131  * Since: 1.12
132  **/
133 void
134 e_flag_wait (EFlag *flag)
135 {
136         g_return_if_fail (flag != NULL);
137
138         g_mutex_lock (&flag->mutex);
139         while (!flag->is_set)
140                 g_cond_wait (&flag->cond, &flag->mutex);
141         g_mutex_unlock (&flag->mutex);
142 }
143
144 /**
145  * e_flag_timed_wait:
146  * @flag: an #EFlag
147  * @abs_time: a #GTimeVal, determining the final time
148  *
149  * Blocks until @flag is set, or until the time specified by @abs_time.
150  * If @flag is already set, the function returns immediately.  The return
151  * value indicates the state of @flag after waiting.
152  *
153  * If @abs_time is %NULL, e_flag_timed_wait() acts like e_flag_wait().
154  *
155  * To easily calculate @abs_time, a combination of g_get_current_time() and
156  * g_time_val_add() can be used.
157  *
158  * Returns: %TRUE if @flag is now set
159  *
160  * Since: 1.12
161  *
162  * Deprecated: 3.8: Use e_flag_wait_until() instead.
163  **/
164 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
165 gboolean
166 e_flag_timed_wait (EFlag *flag,
167                    GTimeVal *abs_time)
168 {
169         gboolean is_set;
170
171         g_return_val_if_fail (flag != NULL, FALSE);
172
173         g_mutex_lock (&flag->mutex);
174         while (!flag->is_set)
175                 if (!g_cond_timed_wait (&flag->cond, &flag->mutex, abs_time))
176                         break;
177         is_set = flag->is_set;
178         g_mutex_unlock (&flag->mutex);
179
180         return is_set;
181 }
182 G_GNUC_END_IGNORE_DEPRECATIONS
183
184 /**
185  * e_flag_wait_until:
186  * @flag: an #EFlag
187  * @end_time: the monotonic time to wait until
188  *
189  * Blocks until @flag is set, or until the time specified by @end_time.
190  * If @flag is already set, the function returns immediately.  The return
191  * value indicates the state of @flag after waiting.
192  *
193  * To easily calculate @end_time, a combination of g_get_monotonic_time() and
194  * G_TIME_SPAN_SECOND macro.
195  *
196  * Returns: %TRUE if @flag is now set
197  *
198  * Since: 3.8
199  **/
200 gboolean
201 e_flag_wait_until (EFlag *flag,
202                    gint64 end_time)
203 {
204         gboolean is_set;
205
206         g_return_val_if_fail (flag != NULL, FALSE);
207
208         g_mutex_lock (&flag->mutex);
209         while (!flag->is_set)
210                 if (!g_cond_wait_until (&flag->cond, &flag->mutex, end_time))
211                         break;
212         is_set = flag->is_set;
213         g_mutex_unlock (&flag->mutex);
214
215         return is_set;
216 }
217
218 /**
219  * e_flag_free:
220  * @flag: an #EFlag
221  *
222  * Destroys @flag.
223  *
224  * Since: 1.12
225  **/
226 void
227 e_flag_free (EFlag *flag)
228 {
229         g_return_if_fail (flag != NULL);
230
231         g_cond_clear (&flag->cond);
232         g_mutex_clear (&flag->mutex);
233         g_slice_free (EFlag, flag);
234 }