D-Bus
1.10.12
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-threads.h D-Bus threads handling 00003 * 00004 * Copyright (C) 2002, 2003, 2006 Red Hat Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 */ 00023 #include <config.h> 00024 #include "dbus-threads.h" 00025 #include "dbus-internals.h" 00026 #include "dbus-threads-internal.h" 00027 #include "dbus-list.h" 00028 00029 static int thread_init_generation = 0; 00030 00052 void 00053 _dbus_rmutex_new_at_location (DBusRMutex **location_p) 00054 { 00055 _dbus_assert (location_p != NULL); 00056 00057 if (!dbus_threads_init_default ()) 00058 { 00059 *location_p = NULL; 00060 return; 00061 } 00062 00063 *location_p = _dbus_platform_rmutex_new (); 00064 } 00065 00076 void 00077 _dbus_cmutex_new_at_location (DBusCMutex **location_p) 00078 { 00079 _dbus_assert (location_p != NULL); 00080 00081 if (!dbus_threads_init_default ()) 00082 { 00083 *location_p = NULL; 00084 return; 00085 } 00086 00087 *location_p = _dbus_platform_cmutex_new (); 00088 } 00089 00093 void 00094 _dbus_rmutex_free_at_location (DBusRMutex **location_p) 00095 { 00096 if (location_p == NULL) 00097 return; 00098 00099 if (*location_p != NULL) 00100 _dbus_platform_rmutex_free (*location_p); 00101 } 00102 00106 void 00107 _dbus_cmutex_free_at_location (DBusCMutex **location_p) 00108 { 00109 if (location_p == NULL) 00110 return; 00111 00112 if (*location_p != NULL) 00113 _dbus_platform_cmutex_free (*location_p); 00114 } 00115 00121 void 00122 _dbus_rmutex_lock (DBusRMutex *mutex) 00123 { 00124 if (mutex == NULL) 00125 return; 00126 00127 _dbus_platform_rmutex_lock (mutex); 00128 } 00129 00135 void 00136 _dbus_cmutex_lock (DBusCMutex *mutex) 00137 { 00138 if (mutex == NULL) 00139 return; 00140 00141 _dbus_platform_cmutex_lock (mutex); 00142 } 00143 00149 void 00150 _dbus_rmutex_unlock (DBusRMutex *mutex) 00151 { 00152 if (mutex == NULL) 00153 return; 00154 00155 _dbus_platform_rmutex_unlock (mutex); 00156 } 00157 00163 void 00164 _dbus_cmutex_unlock (DBusCMutex *mutex) 00165 { 00166 if (mutex == NULL) 00167 return; 00168 00169 _dbus_platform_cmutex_unlock (mutex); 00170 } 00171 00180 DBusCondVar * 00181 _dbus_condvar_new (void) 00182 { 00183 if (!dbus_threads_init_default ()) 00184 return NULL; 00185 00186 return _dbus_platform_condvar_new (); 00187 } 00188 00189 00198 void 00199 _dbus_condvar_new_at_location (DBusCondVar **location_p) 00200 { 00201 _dbus_assert (location_p != NULL); 00202 00203 *location_p = _dbus_condvar_new(); 00204 } 00205 00206 00211 void 00212 _dbus_condvar_free (DBusCondVar *cond) 00213 { 00214 if (cond == NULL) 00215 return; 00216 00217 _dbus_platform_condvar_free (cond); 00218 } 00219 00223 void 00224 _dbus_condvar_free_at_location (DBusCondVar **location_p) 00225 { 00226 if (location_p == NULL) 00227 return; 00228 00229 if (*location_p != NULL) 00230 _dbus_platform_condvar_free (*location_p); 00231 } 00232 00239 void 00240 _dbus_condvar_wait (DBusCondVar *cond, 00241 DBusCMutex *mutex) 00242 { 00243 if (cond == NULL || mutex == NULL) 00244 return; 00245 00246 _dbus_platform_condvar_wait (cond, mutex); 00247 } 00248 00260 dbus_bool_t 00261 _dbus_condvar_wait_timeout (DBusCondVar *cond, 00262 DBusCMutex *mutex, 00263 int timeout_milliseconds) 00264 { 00265 if (cond == NULL || mutex == NULL) 00266 return TRUE; 00267 00268 return _dbus_platform_condvar_wait_timeout (cond, mutex, 00269 timeout_milliseconds); 00270 } 00271 00277 void 00278 _dbus_condvar_wake_one (DBusCondVar *cond) 00279 { 00280 if (cond == NULL) 00281 return; 00282 00283 _dbus_platform_condvar_wake_one (cond); 00284 } 00285 00286 static DBusRMutex *global_locks[_DBUS_N_GLOBAL_LOCKS] = { NULL }; 00287 00288 static void 00289 shutdown_global_locks (void *nil) 00290 { 00291 int i; 00292 00293 for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++) 00294 { 00295 _dbus_assert (global_locks[i] != NULL); 00296 _dbus_platform_rmutex_free (global_locks[i]); 00297 global_locks[i] = NULL; 00298 } 00299 } 00300 00301 static dbus_bool_t 00302 init_global_locks (void) 00303 { 00304 int i; 00305 dbus_bool_t ok; 00306 00307 for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++) 00308 { 00309 _dbus_assert (global_locks[i] == NULL); 00310 00311 global_locks[i] = _dbus_platform_rmutex_new (); 00312 00313 if (global_locks[i] == NULL) 00314 goto failed; 00315 } 00316 00317 _dbus_platform_rmutex_lock (global_locks[_DBUS_LOCK_shutdown_funcs]); 00318 ok = _dbus_register_shutdown_func_unlocked (shutdown_global_locks, NULL); 00319 _dbus_platform_rmutex_unlock (global_locks[_DBUS_LOCK_shutdown_funcs]); 00320 00321 if (!ok) 00322 goto failed; 00323 00324 return TRUE; 00325 00326 failed: 00327 for (i = i - 1; i >= 0; i--) 00328 { 00329 _dbus_platform_rmutex_free (global_locks[i]); 00330 global_locks[i] = NULL; 00331 } 00332 00333 return FALSE; 00334 } 00335 00336 dbus_bool_t 00337 _dbus_lock (DBusGlobalLock lock) 00338 { 00339 _dbus_assert (lock >= 0); 00340 _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); 00341 00342 if (thread_init_generation != _dbus_current_generation && 00343 !dbus_threads_init_default ()) 00344 return FALSE; 00345 00346 _dbus_platform_rmutex_lock (global_locks[lock]); 00347 return TRUE; 00348 } 00349 00350 void 00351 _dbus_unlock (DBusGlobalLock lock) 00352 { 00353 _dbus_assert (lock >= 0); 00354 _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); 00355 00356 _dbus_platform_rmutex_unlock (global_locks[lock]); 00357 } 00358 /* end of internals */ 00360 00390 dbus_bool_t 00391 dbus_threads_init (const DBusThreadFunctions *functions) 00392 { 00393 _dbus_threads_lock_platform_specific (); 00394 00395 if (thread_init_generation == _dbus_current_generation) 00396 { 00397 _dbus_threads_unlock_platform_specific (); 00398 return TRUE; 00399 } 00400 00401 if (!_dbus_threads_init_platform_specific() || 00402 !init_global_locks ()) 00403 { 00404 _dbus_threads_unlock_platform_specific (); 00405 return FALSE; 00406 } 00407 00408 thread_init_generation = _dbus_current_generation; 00409 00410 _dbus_threads_unlock_platform_specific (); 00411 return TRUE; 00412 } 00413 00414 00415 00416 /* Default thread implemenation */ 00417 00437 dbus_bool_t 00438 dbus_threads_init_default (void) 00439 { 00440 return dbus_threads_init (NULL); 00441 } 00442 00443 00446 #ifdef DBUS_ENABLE_EMBEDDED_TESTS 00447 00448 dbus_bool_t 00449 _dbus_threads_init_debug (void) 00450 { 00451 return dbus_threads_init (NULL); 00452 } 00453 00454 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */