D-Bus 1.13.18

dbus-threads.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-threads.h D-Bus threads handling
3 *
4 * Copyright (C) 2002, 2003, 2006 Red Hat Inc.
5 *
6 * Licensed under the Academic Free License version 2.1
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23 #include <config.h>
24 #include "dbus-threads.h"
25 #include "dbus-internals.h"
26 #include "dbus-threads-internal.h"
27 #include "dbus-list.h"
28
29 /* Protected by _dbus_threads_lock_platform_specific() */
30 static int thread_init_generation = 0;
31
53 void
54 _dbus_rmutex_new_at_location (DBusRMutex **location_p)
55 {
56 _dbus_assert (location_p != NULL);
57
58 if (!dbus_threads_init_default ())
59 {
60 *location_p = NULL;
61 return;
62 }
63
64 *location_p = _dbus_platform_rmutex_new ();
65 }
66
77 void
78 _dbus_cmutex_new_at_location (DBusCMutex **location_p)
79 {
80 _dbus_assert (location_p != NULL);
81
82 if (!dbus_threads_init_default ())
83 {
84 *location_p = NULL;
85 return;
86 }
87
88 *location_p = _dbus_platform_cmutex_new ();
89 }
90
94 void
95 _dbus_rmutex_free_at_location (DBusRMutex **location_p)
96 {
97 if (location_p == NULL)
98 return;
99
100 if (*location_p != NULL)
101 _dbus_platform_rmutex_free (*location_p);
102 }
103
107 void
108 _dbus_cmutex_free_at_location (DBusCMutex **location_p)
109 {
110 if (location_p == NULL)
111 return;
112
113 if (*location_p != NULL)
114 _dbus_platform_cmutex_free (*location_p);
115 }
116
122 void
123 _dbus_rmutex_lock (DBusRMutex *mutex)
124 {
125 if (mutex == NULL)
126 return;
127
128 _dbus_platform_rmutex_lock (mutex);
129 }
130
136 void
137 _dbus_cmutex_lock (DBusCMutex *mutex)
138 {
139 if (mutex == NULL)
140 return;
141
142 _dbus_platform_cmutex_lock (mutex);
143 }
144
150 void
151 _dbus_rmutex_unlock (DBusRMutex *mutex)
152 {
153 if (mutex == NULL)
154 return;
155
156 _dbus_platform_rmutex_unlock (mutex);
157 }
158
164 void
165 _dbus_cmutex_unlock (DBusCMutex *mutex)
166 {
167 if (mutex == NULL)
168 return;
169
170 _dbus_platform_cmutex_unlock (mutex);
171 }
172
181 DBusCondVar *
182 _dbus_condvar_new (void)
183 {
184 if (!dbus_threads_init_default ())
185 return NULL;
186
187 return _dbus_platform_condvar_new ();
188 }
189
190
199 void
200 _dbus_condvar_new_at_location (DBusCondVar **location_p)
201 {
202 _dbus_assert (location_p != NULL);
203
204 *location_p = _dbus_condvar_new();
205 }
206
207
212 void
213 _dbus_condvar_free (DBusCondVar *cond)
214 {
215 if (cond == NULL)
216 return;
217
218 _dbus_platform_condvar_free (cond);
219 }
220
224 void
225 _dbus_condvar_free_at_location (DBusCondVar **location_p)
226 {
227 if (location_p == NULL)
228 return;
229
230 if (*location_p != NULL)
231 _dbus_platform_condvar_free (*location_p);
232 }
233
240 void
241 _dbus_condvar_wait (DBusCondVar *cond,
242 DBusCMutex *mutex)
243 {
244 if (cond == NULL || mutex == NULL)
245 return;
246
247 _dbus_platform_condvar_wait (cond, mutex);
248 }
249
261 dbus_bool_t
262 _dbus_condvar_wait_timeout (DBusCondVar *cond,
263 DBusCMutex *mutex,
264 int timeout_milliseconds)
265 {
266 if (cond == NULL || mutex == NULL)
267 return TRUE;
268
269 return _dbus_platform_condvar_wait_timeout (cond, mutex,
270 timeout_milliseconds);
271 }
272
278 void
279 _dbus_condvar_wake_one (DBusCondVar *cond)
280 {
281 if (cond == NULL)
282 return;
283
284 _dbus_platform_condvar_wake_one (cond);
285 }
286
287 /* Protected by _dbus_threads_lock_platform_specific() */
288 static DBusRMutex *global_locks[_DBUS_N_GLOBAL_LOCKS] = { NULL };
289
290 static void
291 shutdown_global_locks (void *nil)
292 {
293 int i;
294
295 for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++)
296 {
297 _dbus_assert (global_locks[i] != NULL);
298 _dbus_platform_rmutex_free (global_locks[i]);
299 global_locks[i] = NULL;
300 }
301 }
302
303 static dbus_bool_t
304 init_global_locks (void)
305 {
306 int i;
307 dbus_bool_t ok;
308
309 for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++)
310 {
311 _dbus_assert (global_locks[i] == NULL);
312
313 global_locks[i] = _dbus_platform_rmutex_new ();
314
315 if (global_locks[i] == NULL)
316 goto failed;
317 }
318
319 _dbus_platform_rmutex_lock (global_locks[_DBUS_LOCK_shutdown_funcs]);
320 ok = _dbus_register_shutdown_func_unlocked (shutdown_global_locks, NULL);
321 _dbus_platform_rmutex_unlock (global_locks[_DBUS_LOCK_shutdown_funcs]);
322
323 if (!ok)
324 goto failed;
325
326 return TRUE;
327
328 failed:
329 for (i = i - 1; i >= 0; i--)
330 {
331 _dbus_platform_rmutex_free (global_locks[i]);
332 global_locks[i] = NULL;
333 }
334
335 return FALSE;
336 }
337
338 dbus_bool_t
339 _dbus_lock (DBusGlobalLock lock)
340 {
341 _dbus_assert (lock >= 0);
342 _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS);
343
344 if (thread_init_generation != _dbus_current_generation &&
345 !dbus_threads_init_default ())
346 return FALSE;
347
348 _dbus_platform_rmutex_lock (global_locks[lock]);
349 return TRUE;
350 }
351
352 void
353 _dbus_unlock (DBusGlobalLock lock)
354 {
355 _dbus_assert (lock >= 0);
356 _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS);
357
358 _dbus_platform_rmutex_unlock (global_locks[lock]);
359 }
360 /* end of internals */
362
392 dbus_bool_t
393 dbus_threads_init (const DBusThreadFunctions *functions)
394 {
395 _dbus_threads_lock_platform_specific ();
396
397 if (thread_init_generation == _dbus_current_generation)
398 {
399 _dbus_threads_unlock_platform_specific ();
400 return TRUE;
401 }
402
403 if (!_dbus_threads_init_platform_specific() ||
404 !init_global_locks ())
405 {
406 _dbus_threads_unlock_platform_specific ();
407 return FALSE;
408 }
409
410 thread_init_generation = _dbus_current_generation;
411
412 _dbus_threads_unlock_platform_specific ();
413 return TRUE;
414 }
415
416
417
418 /* Default thread implemenation */
419
439 dbus_bool_t
440 dbus_threads_init_default (void)
441 {
442 return dbus_threads_init (NULL);
443 }
444
445
448 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
449
450 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
DBusRMutex
Definition: dbus-sysdeps-pthread.c:49
_dbus_threads_lock_platform_specific
void _dbus_threads_lock_platform_specific(void)
Lock a static mutex used to protect _dbus_threads_init_platform_specific().
Definition: dbus-sysdeps-pthread.c:294
DBusThreadFunctions
Functions that must be implemented to make the D-Bus library thread-aware.
Definition: dbus-threads.h:153
_dbus_condvar_wake_one
void _dbus_condvar_wake_one(DBusCondVar *cond)
If there are threads waiting on the condition variable, wake up exactly one.
Definition: dbus-threads.c:279
DBusCMutex
Definition: dbus-sysdeps-pthread.c:53
_dbus_current_generation
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called,...
Definition: dbus-memory.c:784
_dbus_condvar_free
void _dbus_condvar_free(DBusCondVar *cond)
Frees a conditional variable created with dbus_condvar_new(); does nothing if passed a NULL pointer.
Definition: dbus-threads.c:213
DBusCondVar
Definition: dbus-sysdeps-pthread.c:57
_dbus_condvar_free_at_location
void _dbus_condvar_free_at_location(DBusCondVar **location_p)
Frees a condition variable; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:225
DBusCMutex::lock
pthread_mutex_t lock
the lock
Definition: dbus-sysdeps-pthread.c:54
_dbus_condvar_wait_timeout
dbus_bool_t _dbus_condvar_wait_timeout(DBusCondVar *cond, DBusCMutex *mutex, int timeout_milliseconds)
Atomically unlocks the mutex and waits for the conditions variable to be signalled,...
Definition: dbus-threads.c:262
_dbus_condvar_wait
void _dbus_condvar_wait(DBusCondVar *cond, DBusCMutex *mutex)
Atomically unlocks the mutex and waits for the conditions variable to be signalled.
Definition: dbus-threads.c:241
TRUE
#define TRUE
_dbus_cmutex_unlock
void _dbus_cmutex_unlock(DBusCMutex *mutex)
Unlocks a mutex.
Definition: dbus-threads.c:165
_dbus_cmutex_new_at_location
void _dbus_cmutex_new_at_location(DBusCMutex **location_p)
Creates a new mutex or creates a no-op mutex if threads are not initialized.
Definition: dbus-threads.c:78
_dbus_rmutex_unlock
void _dbus_rmutex_unlock(DBusRMutex *mutex)
Unlocks a mutex.
Definition: dbus-threads.c:151
FALSE
#define FALSE
_dbus_threads_init_platform_specific
dbus_bool_t _dbus_threads_init_platform_specific(void)
Initialize threads as in dbus_threads_init_default(), appropriately for the platform.
Definition: dbus-sysdeps-pthread.c:279
_dbus_cmutex_lock
void _dbus_cmutex_lock(DBusCMutex *mutex)
Locks a mutex.
Definition: dbus-threads.c:137
dbus_threads_init_default
dbus_bool_t dbus_threads_init_default(void)
Initializes threads.
Definition: dbus-threads.c:440
_dbus_rmutex_lock
void _dbus_rmutex_lock(DBusRMutex *mutex)
Locks a mutex.
Definition: dbus-threads.c:123
_dbus_threads_unlock_platform_specific
void _dbus_threads_unlock_platform_specific(void)
Undo _dbus_threads_lock_platform_specific().
Definition: dbus-sysdeps-pthread.c:300
_dbus_assert
#define _dbus_assert(condition)
Definition: dbus-internals.h:153
_dbus_condvar_new_at_location
void _dbus_condvar_new_at_location(DBusCondVar **location_p)
This does the same thing as _dbus_condvar_new.
Definition: dbus-threads.c:200
dbus_threads_init
dbus_bool_t dbus_threads_init(const DBusThreadFunctions *functions)
Initializes threads, like dbus_threads_init_default().
Definition: dbus-threads.c:393
_dbus_cmutex_free_at_location
void _dbus_cmutex_free_at_location(DBusCMutex **location_p)
Frees a DBusCMutex; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:108
_dbus_condvar_new
DBusCondVar * _dbus_condvar_new(void)
Creates a new condition variable using the function supplied to dbus_threads_init(),...
Definition: dbus-threads.c:182
_dbus_rmutex_free_at_location
void _dbus_rmutex_free_at_location(DBusRMutex **location_p)
Frees a DBusRMutex; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:95
_dbus_rmutex_new_at_location
void _dbus_rmutex_new_at_location(DBusRMutex **location_p)
Creates a new mutex or creates a no-op mutex if threads are not initialized.
Definition: dbus-threads.c:54
dbus_bool_t
dbus_uint32_t dbus_bool_t
Definition: dbus-types.h:35
NULL
#define NULL