From 02d1847d9286eafde38c63c3e5c754b9fceab866 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 17 Feb 2012 13:34:36 +0000 Subject: [PATCH] Never use non-libdbus threading primitives This lets us simplify considerably, by assuming that we always have both recursive and suitable-for-condition-variable mutexes. The Windows implementation has been compiled (on 32-bit mingw-w64) but not tested. Justification for the approach used on Windows, and in particular, using the existing "non-recursive" locks as if they were recursive: * We've been using them in conjunction with condition variables all along, so they'd better be suitable * On fd.o #36204, Ralf points out that mutexes created via CreateMutex are, in fact, recursive * Havoc's admonitions about requiring "Java-style" recursive locking (waiting for a condition variable while holding a recursive lock requires releasing that lock n times) turn out not to apply to either of our uses of DBusCondVar in DBusConnection, because the lock is only held for a short time, without calling into user code; indeed, our Unix implementation isn't recursive anyway, so if the Windows implementation reaches the deadlocking situation somehow (waiting for condition variable while locked more than once), the Unix implementation would already have deadlocked on the same code path (trying to lock more than once) One possible alternative to a CreateMutex mutex for use with condition variables would be a CRITICAL_SECTION. I'm not going to implement this, but Windows developers are welcome to do so. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=36204 Bug: https://bugs.freedesktop.org/show_bug.cgi?id=43744 --- dbus/dbus-sysdeps-pthread.c | 169 +++++------- dbus/dbus-sysdeps-thread-win.c | 110 ++++---- dbus/dbus-threads-internal.h | 22 ++ dbus/dbus-threads.c | 606 ++++++++++------------------------------ 4 files changed, 291 insertions(+), 616 deletions(-) diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c index 062b53e..9758934 100644 --- a/dbus/dbus-sysdeps-pthread.c +++ b/dbus/dbus-sysdeps-pthread.c @@ -43,13 +43,17 @@ */ static dbus_bool_t have_monotonic_clock = 0; -typedef struct { +struct DBusRMutex { pthread_mutex_t lock; /**< the lock */ -} DBusMutexPThread; +}; + +struct DBusCMutex { + pthread_mutex_t lock; /**< the lock */ +}; -typedef struct { +struct DBusCondVar { pthread_cond_t cond; /**< the condition */ -} DBusCondVarPThread; +}; #define DBUS_MUTEX(m) ((DBusMutex*) m) #define DBUS_MUTEX_PTHREAD(m) ((DBusMutexPThread*) m) @@ -72,13 +76,13 @@ typedef struct { } while (0) #endif /* !DBUS_DISABLE_ASSERT */ -static DBusMutex * -_dbus_pthread_cmutex_new (void) +DBusCMutex * +_dbus_platform_cmutex_new (void) { - DBusMutexPThread *pmutex; + DBusCMutex *pmutex; int result; - pmutex = dbus_new (DBusMutexPThread, 1); + pmutex = dbus_new (DBusCMutex, 1); if (pmutex == NULL) return NULL; @@ -94,17 +98,17 @@ _dbus_pthread_cmutex_new (void) PTHREAD_CHECK ("pthread_mutex_init", result); } - return DBUS_MUTEX (pmutex); + return pmutex; } -static DBusMutex * -_dbus_pthread_rmutex_new (void) +DBusRMutex * +_dbus_platform_rmutex_new (void) { - DBusMutexPThread *pmutex; + DBusRMutex *pmutex; pthread_mutexattr_t mutexattr; int result; - pmutex = dbus_new (DBusMutexPThread, 1); + pmutex = dbus_new (DBusRMutex, 1); if (pmutex == NULL) return NULL; @@ -123,44 +127,55 @@ _dbus_pthread_rmutex_new (void) PTHREAD_CHECK ("pthread_mutex_init", result); } - return DBUS_MUTEX (pmutex); + return pmutex; } -static void -_dbus_pthread_mutex_free (DBusMutex *mutex) +void +_dbus_platform_cmutex_free (DBusCMutex *mutex) { - DBusMutexPThread *pmutex = DBUS_MUTEX_PTHREAD (mutex); + PTHREAD_CHECK ("pthread_mutex_destroy", pthread_mutex_destroy (&mutex->lock)); + dbus_free (mutex); +} - PTHREAD_CHECK ("pthread_mutex_destroy", pthread_mutex_destroy (&pmutex->lock)); - dbus_free (pmutex); +void +_dbus_platform_rmutex_free (DBusRMutex *mutex) +{ + PTHREAD_CHECK ("pthread_mutex_destroy", pthread_mutex_destroy (&mutex->lock)); + dbus_free (mutex); } -static dbus_bool_t -_dbus_pthread_mutex_lock (DBusMutex *mutex) +void +_dbus_platform_cmutex_lock (DBusCMutex *mutex) { - DBusMutexPThread *pmutex = DBUS_MUTEX_PTHREAD (mutex); + PTHREAD_CHECK ("pthread_mutex_lock", pthread_mutex_lock (&mutex->lock)); +} - PTHREAD_CHECK ("pthread_mutex_lock", pthread_mutex_lock (&pmutex->lock)); - return TRUE; +void +_dbus_platform_rmutex_lock (DBusRMutex *mutex) +{ + PTHREAD_CHECK ("pthread_mutex_lock", pthread_mutex_lock (&mutex->lock)); } -static dbus_bool_t -_dbus_pthread_mutex_unlock (DBusMutex *mutex) +void +_dbus_platform_cmutex_unlock (DBusCMutex *mutex) { - DBusMutexPThread *pmutex = DBUS_MUTEX_PTHREAD (mutex); + PTHREAD_CHECK ("pthread_mutex_unlock", pthread_mutex_unlock (&mutex->lock)); +} - PTHREAD_CHECK ("pthread_mutex_unlock", pthread_mutex_unlock (&pmutex->lock)); - return TRUE; +void +_dbus_platform_rmutex_unlock (DBusRMutex *mutex) +{ + PTHREAD_CHECK ("pthread_mutex_unlock", pthread_mutex_unlock (&mutex->lock)); } -static DBusCondVar * -_dbus_pthread_condvar_new (void) +DBusCondVar * +_dbus_platform_condvar_new (void) { - DBusCondVarPThread *pcond; + DBusCondVar *pcond; pthread_condattr_t attr; int result; - pcond = dbus_new (DBusCondVarPThread, 1); + pcond = dbus_new (DBusCondVar, 1); if (pcond == NULL) return NULL; @@ -183,36 +198,28 @@ _dbus_pthread_condvar_new (void) PTHREAD_CHECK ("pthread_cond_init", result); } - return DBUS_COND_VAR (pcond); + return pcond; } -static void -_dbus_pthread_condvar_free (DBusCondVar *cond) -{ - DBusCondVarPThread *pcond = DBUS_COND_VAR_PTHREAD (cond); - - PTHREAD_CHECK ("pthread_cond_destroy", pthread_cond_destroy (&pcond->cond)); - - dbus_free (pcond); +void +_dbus_platform_condvar_free (DBusCondVar *cond) +{ + PTHREAD_CHECK ("pthread_cond_destroy", pthread_cond_destroy (&cond->cond)); + dbus_free (cond); } -static void -_dbus_pthread_condvar_wait (DBusCondVar *cond, - DBusMutex *mutex) +void +_dbus_platform_condvar_wait (DBusCondVar *cond, + DBusCMutex *mutex) { - DBusMutexPThread *pmutex = DBUS_MUTEX_PTHREAD (mutex); - DBusCondVarPThread *pcond = DBUS_COND_VAR_PTHREAD (cond); - - PTHREAD_CHECK ("pthread_cond_wait", pthread_cond_wait (&pcond->cond, &pmutex->lock)); + PTHREAD_CHECK ("pthread_cond_wait", pthread_cond_wait (&cond->cond, &mutex->lock)); } -static dbus_bool_t -_dbus_pthread_condvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, - int timeout_milliseconds) +dbus_bool_t +_dbus_platform_condvar_wait_timeout (DBusCondVar *cond, + DBusCMutex *mutex, + int timeout_milliseconds) { - DBusMutexPThread *pmutex = DBUS_MUTEX_PTHREAD (mutex); - DBusCondVarPThread *pcond = DBUS_COND_VAR_PTHREAD (cond); struct timeval time_now; struct timespec end_time; int result; @@ -238,7 +245,7 @@ _dbus_pthread_condvar_wait_timeout (DBusCondVar *cond, end_time.tv_nsec -= 1000*1000*1000; } - result = pthread_cond_timedwait (&pcond->cond, &pmutex->lock, &end_time); + result = pthread_cond_timedwait (&cond->cond, &mutex->lock, &end_time); if (result != ETIMEDOUT) { @@ -249,54 +256,18 @@ _dbus_pthread_condvar_wait_timeout (DBusCondVar *cond, return result != ETIMEDOUT; } -static void -_dbus_pthread_condvar_wake_one (DBusCondVar *cond) +void +_dbus_platform_condvar_wake_one (DBusCondVar *cond) { - DBusCondVarPThread *pcond = DBUS_COND_VAR_PTHREAD (cond); - - PTHREAD_CHECK ("pthread_cond_signal", pthread_cond_signal (&pcond->cond)); + PTHREAD_CHECK ("pthread_cond_signal", pthread_cond_signal (&cond->cond)); } -static void -_dbus_pthread_condvar_wake_all (DBusCondVar *cond) +void +_dbus_platform_condvar_wake_all (DBusCondVar *cond) { - DBusCondVarPThread *pcond = DBUS_COND_VAR_PTHREAD (cond); - - PTHREAD_CHECK ("pthread_cond_broadcast", pthread_cond_broadcast (&pcond->cond)); + PTHREAD_CHECK ("pthread_cond_broadcast", pthread_cond_broadcast (&cond->cond)); } -static const DBusThreadFunctions pthread_functions = -{ - DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK | - DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK | - DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK | - DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK | - DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, - _dbus_pthread_cmutex_new, - _dbus_pthread_mutex_free, - _dbus_pthread_mutex_lock, - _dbus_pthread_mutex_unlock, - _dbus_pthread_condvar_new, - _dbus_pthread_condvar_free, - _dbus_pthread_condvar_wait, - _dbus_pthread_condvar_wait_timeout, - _dbus_pthread_condvar_wake_one, - _dbus_pthread_condvar_wake_all, - _dbus_pthread_rmutex_new, - _dbus_pthread_mutex_free, - (void (*) (DBusMutex *)) _dbus_pthread_mutex_lock, - (void (*) (DBusMutex *)) _dbus_pthread_mutex_unlock -}; - static void check_monotonic_clock (void) { @@ -311,5 +282,5 @@ dbus_bool_t _dbus_threads_init_platform_specific (void) { check_monotonic_clock (); - return dbus_threads_init (&pthread_functions); + return dbus_threads_init (NULL); } diff --git a/dbus/dbus-sysdeps-thread-win.c b/dbus/dbus-sysdeps-thread-win.c index e2972a3..db48619 100644 --- a/dbus/dbus-sysdeps-thread-win.c +++ b/dbus/dbus-sysdeps-thread-win.c @@ -90,34 +90,60 @@ DllMain (hinst_t hinstDLL, return TRUE; } -static DBusMutex* -_dbus_windows_mutex_new (void) +DBusCMutex * +_dbus_platform_cmutex_new (void) { HANDLE handle; handle = CreateMutex (NULL, FALSE, NULL); - return (DBusMutex *) handle; + return (DBusCMutex *) handle; } -static void -_dbus_windows_mutex_free (DBusMutex *mutex) +DBusRMutex * +_dbus_platform_rmutex_new (void) +{ + HANDLE handle; + handle = CreateMutex (NULL, FALSE, NULL); + return (DBusRMutex *) handle; +} + +void +_dbus_platform_cmutex_free (DBusCMutex *mutex) { CloseHandle ((HANDLE *) mutex); } -static dbus_bool_t -_dbus_windows_mutex_lock (DBusMutex *mutex) +void +_dbus_platform_rmutex_free (DBusRMutex *mutex) { - return WaitForSingleObject ((HANDLE *) mutex, INFINITE) != WAIT_FAILED; + CloseHandle ((HANDLE *) mutex); } -static dbus_bool_t -_dbus_windows_mutex_unlock (DBusMutex *mutex) +void +_dbus_platform_cmutex_lock (DBusCMutex *mutex) +{ + WaitForSingleObject ((HANDLE *) mutex, INFINITE); +} + +void +_dbus_platform_rmutex_lock (DBusRMutex *mutex) { - return ReleaseMutex ((HANDLE *) mutex) != 0; + WaitForSingleObject ((HANDLE *) mutex, INFINITE); } -static DBusCondVar * -_dbus_windows_condvar_new (void) +void +_dbus_platform_cmutex_unlock (DBusCMutex *mutex) +{ + ReleaseMutex ((HANDLE *) mutex); +} + +void +_dbus_platform_rmutex_unlock (DBusRMutex *mutex) +{ + ReleaseMutex ((HANDLE *) mutex); +} + +DBusCondVar * +_dbus_platform_condvar_new (void) { DBusCondVar *cond; @@ -128,11 +154,11 @@ _dbus_windows_condvar_new (void) cond->list = NULL; InitializeCriticalSection (&cond->lock); - return (DBusCondVar *) cond; + return cond; } -static void -_dbus_windows_condvar_free (DBusCondVar *cond) +void +_dbus_platform_condvar_free (DBusCondVar *cond) { DeleteCriticalSection (&cond->lock); _dbus_list_clear (&cond->list); @@ -141,7 +167,7 @@ _dbus_windows_condvar_free (DBusCondVar *cond) static dbus_bool_t _dbus_condvar_wait_win32 (DBusCondVar *cond, - DBusMutex *mutex, + DBusCMutex *mutex, int milliseconds) { DWORD retval; @@ -168,9 +194,9 @@ _dbus_condvar_wait_win32 (DBusCondVar *cond, if (!ret) return FALSE; /* Prepend failed */ - _dbus_mutex_unlock (mutex); + _dbus_platform_cmutex_unlock (mutex); retval = WaitForSingleObject (event, milliseconds); - _dbus_mutex_lock (mutex); + _dbus_platform_cmutex_lock (mutex); if (retval == WAIT_TIMEOUT) { @@ -198,23 +224,23 @@ _dbus_condvar_wait_win32 (DBusCondVar *cond, return retval != WAIT_TIMEOUT; } -static void -_dbus_windows_condvar_wait (DBusCondVar *cond, - DBusMutex *mutex) +void +_dbus_platform_condvar_wait (DBusCondVar *cond, + DBusCMutex *mutex) { _dbus_condvar_wait_win32 (cond, mutex, INFINITE); } -static dbus_bool_t -_dbus_windows_condvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, +dbus_bool_t +_dbus_platform_condvar_wait_timeout (DBusCondVar *cond, + DBusCMutex *mutex, int timeout_milliseconds) { return _dbus_condvar_wait_win32 (cond, mutex, timeout_milliseconds); } -static void -_dbus_windows_condvar_wake_one (DBusCondVar *cond) +void +_dbus_platform_condvar_wake_one (DBusCondVar *cond) { EnterCriticalSection (&cond->lock); @@ -230,8 +256,8 @@ _dbus_windows_condvar_wake_one (DBusCondVar *cond) LeaveCriticalSection (&cond->lock); } -static void -_dbus_windows_condvar_wake_all (DBusCondVar *cond) +void +_dbus_platform_condvar_wake_all (DBusCondVar *cond) { EnterCriticalSection (&cond->lock); @@ -250,30 +276,6 @@ _dbus_windows_condvar_wake_all (DBusCondVar *cond) LeaveCriticalSection (&cond->lock); } -static const DBusThreadFunctions windows_functions = -{ - DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, - _dbus_windows_mutex_new, - _dbus_windows_mutex_free, - _dbus_windows_mutex_lock, - _dbus_windows_mutex_unlock, - _dbus_windows_condvar_new, - _dbus_windows_condvar_free, - _dbus_windows_condvar_wait, - _dbus_windows_condvar_wait_timeout, - _dbus_windows_condvar_wake_one, - _dbus_windows_condvar_wake_all -}; - dbus_bool_t _dbus_threads_init_platform_specific (void) { @@ -287,6 +289,6 @@ _dbus_threads_init_platform_specific (void) return FALSE; } - return dbus_threads_init (&windows_functions); + return dbus_threads_init (NULL); } diff --git a/dbus/dbus-threads-internal.h b/dbus/dbus-threads-internal.h index 2561136..680a603 100644 --- a/dbus/dbus-threads-internal.h +++ b/dbus/dbus-threads-internal.h @@ -70,6 +70,28 @@ void _dbus_condvar_wake_all (DBusCondVar *cond); void _dbus_condvar_new_at_location (DBusCondVar **location_p); void _dbus_condvar_free_at_location (DBusCondVar **location_p); +/* Private to threading implementations and dbus-threads.c */ + +DBusRMutex *_dbus_platform_rmutex_new (void); +void _dbus_platform_rmutex_free (DBusRMutex *mutex); +void _dbus_platform_rmutex_lock (DBusRMutex *mutex); +void _dbus_platform_rmutex_unlock (DBusRMutex *mutex); + +DBusCMutex *_dbus_platform_cmutex_new (void); +void _dbus_platform_cmutex_free (DBusCMutex *mutex); +void _dbus_platform_cmutex_lock (DBusCMutex *mutex); +void _dbus_platform_cmutex_unlock (DBusCMutex *mutex); + +DBusCondVar* _dbus_platform_condvar_new (void); +void _dbus_platform_condvar_free (DBusCondVar *cond); +void _dbus_platform_condvar_wait (DBusCondVar *cond, + DBusCMutex *mutex); +dbus_bool_t _dbus_platform_condvar_wait_timeout (DBusCondVar *cond, + DBusCMutex *mutex, + int timeout_milliseconds); +void _dbus_platform_condvar_wake_one (DBusCondVar *cond); +void _dbus_platform_condvar_wake_all (DBusCondVar *cond); + DBUS_END_DECLS #endif /* DBUS_THREADS_INTERNAL_H */ diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c index 02b4199..2c9ac2c 100644 --- a/dbus/dbus-threads.c +++ b/dbus/dbus-threads.c @@ -26,16 +26,6 @@ #include "dbus-threads-internal.h" #include "dbus-list.h" -static DBusThreadFunctions thread_functions = -{ - 0, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - - NULL, NULL, NULL, NULL -}; - static int thread_init_generation = 0; static DBusList *uninitialized_rmutex_list = NULL; @@ -44,6 +34,8 @@ static DBusList *uninitialized_condvar_list = NULL; /** This is used for the no-op default mutex pointer, just to be distinct from #NULL */ #define _DBUS_DUMMY_MUTEX ((DBusMutex*)0xABCDEF) +#define _DBUS_DUMMY_RMUTEX ((DBusRMutex *) _DBUS_DUMMY_MUTEX) +#define _DBUS_DUMMY_CMUTEX ((DBusCMutex *) _DBUS_DUMMY_MUTEX) /** This is used for the no-op default mutex pointer, just to be distinct from #NULL */ #define _DBUS_DUMMY_CONDVAR ((DBusCondVar*)0xABCDEF2) @@ -68,25 +60,27 @@ static void _dbus_mutex_free_at_location (DBusMutex **location_p, */ /* - * Create a new mutex. - * - * ctor should be either thread_functions.mutex_new or - * thread_functions.recursive_mutex_new. It will be used if possible; - * if #NULL, the other version will be used. - * - * @param ctor a preferred constructor for a new mutex + * Create a new recursive mutex. + */ +static DBusRMutex * +_dbus_rmutex_new (void) +{ + if (thread_init_generation == _dbus_current_generation) + return _dbus_platform_rmutex_new (); + else + return _DBUS_DUMMY_RMUTEX; +} + +/* + * Create a new mutex suitable for use with condition variables. */ -static DBusMutex * -_dbus_mutex_new (DBusMutexNewFunction ctor) +static DBusCMutex * +_dbus_cmutex_new (void) { - if (ctor) - return ctor (); - else if (thread_functions.recursive_mutex_new) - return (* thread_functions.recursive_mutex_new) (); - else if (thread_functions.mutex_new) - return (* thread_functions.mutex_new) (); + if (thread_init_generation == _dbus_current_generation) + return _dbus_platform_cmutex_new (); else - return _DBUS_DUMMY_MUTEX; + return _DBUS_DUMMY_CMUTEX; } /** @@ -108,10 +102,19 @@ _dbus_mutex_new (DBusMutexNewFunction ctor) void _dbus_rmutex_new_at_location (DBusRMutex **location_p) { - _dbus_mutex_new_at_location ((DBusMutex **) location_p, - thread_functions.recursive_mutex_new, - thread_functions.recursive_mutex_free, - &uninitialized_rmutex_list); + _dbus_assert (location_p != NULL); + + if (thread_init_generation == _dbus_current_generation) + { + *location_p = _dbus_platform_rmutex_new (); + } + else + { + *location_p = _DBUS_DUMMY_RMUTEX; + + if (!_dbus_list_append (&uninitialized_rmutex_list, location_p)) + *location_p = NULL; + } } /** @@ -132,98 +135,42 @@ _dbus_rmutex_new_at_location (DBusRMutex **location_p) void _dbus_cmutex_new_at_location (DBusCMutex **location_p) { - _dbus_mutex_new_at_location ((DBusMutex **) location_p, - thread_functions.mutex_new, - thread_functions.mutex_free, - &uninitialized_cmutex_list); -} - -/* - * Implementation of _dbus_rmutex_new_at_location() and - * _dbus_cmutex_new_at_location(). - * - * @param location_p the location of the new mutex, can return #NULL on OOM - * @param ctor as for _dbus_mutex_new() - * @param dtor the destructor corresponding to ctor, to unwind on error - * @param uninitialized uninitialized_cmutex_list or uninitialized_rmutex_list - */ -static void -_dbus_mutex_new_at_location (DBusMutex **location_p, - DBusMutexNewFunction ctor, - DBusMutexFreeFunction dtor, - DBusList **uninitialized) -{ _dbus_assert (location_p != NULL); - *location_p = _dbus_mutex_new (ctor); - - if (thread_init_generation != _dbus_current_generation && *location_p) + if (thread_init_generation == _dbus_current_generation) { - if (!_dbus_list_append (uninitialized, location_p)) - { - _dbus_mutex_free (*location_p, dtor); - *location_p = NULL; - } + *location_p = _dbus_platform_cmutex_new (); } -} - -/* - * Free a mutex. - * - * dtor should be either thread_functions.mutex_free or - * thread_functions.recursive_mutex_free. It will be used if possible; - * if NULL, the other version will be used. - * - * @param dtor a preferred destructor for the mutex - */ -static void -_dbus_mutex_free (DBusMutex *mutex, - DBusMutexFreeFunction dtor) -{ - if (mutex) - { - if (dtor) - dtor (mutex); - else if (mutex && thread_functions.recursive_mutex_free) - (* thread_functions.recursive_mutex_free) (mutex); - else if (mutex && thread_functions.mutex_free) - (* thread_functions.mutex_free) (mutex); - } -} - -/* - * Implementation of _dbus_rmutex_free_at_location() and - * _dbus_cmutex_free_at_location(). - * - * @param location_p the location of the mutex or #NULL - * @param dtor as for _dbus_mutex_free() - * @param uninitialized uninitialized_cmutex_list or uninitialized_rmutex_list - */ -static void -_dbus_mutex_free_at_location (DBusMutex **location_p, - DBusMutexFreeFunction dtor, - DBusList **uninitialized) -{ - if (location_p) + else { - if (thread_init_generation != _dbus_current_generation) - _dbus_list_remove (uninitialized, location_p); + *location_p = _DBUS_DUMMY_CMUTEX; - _dbus_mutex_free (*location_p, dtor); + if (!_dbus_list_append (&uninitialized_cmutex_list, location_p)) + *location_p = NULL; } } /** - * Frees a DBusRMutex and removes it from the - * uninitialized mutex list; + * Frees a DBusRMutex or removes it from the uninitialized mutex list; * does nothing if passed a #NULL pointer. */ void _dbus_rmutex_free_at_location (DBusRMutex **location_p) { - _dbus_mutex_free_at_location ((DBusMutex **) location_p, - thread_functions.recursive_mutex_free, - &uninitialized_rmutex_list); + if (location_p == NULL) + return; + + if (thread_init_generation == _dbus_current_generation) + { + if (*location_p != NULL) + _dbus_platform_rmutex_free (*location_p); + } + else + { + _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_RMUTEX); + + _dbus_list_remove (&uninitialized_rmutex_list, location_p); + } } /** @@ -234,9 +181,20 @@ _dbus_rmutex_free_at_location (DBusRMutex **location_p) void _dbus_cmutex_free_at_location (DBusCMutex **location_p) { - _dbus_mutex_free_at_location ((DBusMutex **) location_p, - thread_functions.mutex_free, - &uninitialized_cmutex_list); + if (location_p == NULL) + return; + + if (thread_init_generation == _dbus_current_generation) + { + if (*location_p != NULL) + _dbus_platform_cmutex_free (*location_p); + } + else + { + _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_CMUTEX); + + _dbus_list_remove (&uninitialized_cmutex_list, location_p); + } } /** @@ -247,13 +205,8 @@ _dbus_cmutex_free_at_location (DBusCMutex **location_p) void _dbus_rmutex_lock (DBusRMutex *mutex) { - if (mutex) - { - if (thread_functions.recursive_mutex_lock) - (* thread_functions.recursive_mutex_lock) ((DBusMutex *) mutex); - else if (thread_functions.mutex_lock) - (* thread_functions.mutex_lock) ((DBusMutex *) mutex); - } + if (mutex && thread_init_generation == _dbus_current_generation) + _dbus_platform_rmutex_lock (mutex); } /** @@ -264,13 +217,8 @@ _dbus_rmutex_lock (DBusRMutex *mutex) void _dbus_cmutex_lock (DBusCMutex *mutex) { - if (mutex) - { - if (thread_functions.mutex_lock) - (* thread_functions.mutex_lock) ((DBusMutex *) mutex); - else if (thread_functions.recursive_mutex_lock) - (* thread_functions.recursive_mutex_lock) ((DBusMutex *) mutex); - } + if (mutex && thread_init_generation == _dbus_current_generation) + _dbus_platform_cmutex_lock (mutex); } /** @@ -281,13 +229,8 @@ _dbus_cmutex_lock (DBusCMutex *mutex) void _dbus_rmutex_unlock (DBusRMutex *mutex) { - if (mutex) - { - if (thread_functions.recursive_mutex_unlock) - (* thread_functions.recursive_mutex_unlock) ((DBusMutex *) mutex); - else if (thread_functions.mutex_unlock) - (* thread_functions.mutex_unlock) ((DBusMutex *) mutex); - } + if (mutex && thread_init_generation == _dbus_current_generation) + _dbus_platform_rmutex_unlock (mutex); } /** @@ -298,13 +241,8 @@ _dbus_rmutex_unlock (DBusRMutex *mutex) void _dbus_cmutex_unlock (DBusCMutex *mutex) { - if (mutex) - { - if (thread_functions.mutex_unlock) - (* thread_functions.mutex_unlock) ((DBusMutex *) mutex); - else if (thread_functions.recursive_mutex_unlock) - (* thread_functions.recursive_mutex_unlock) ((DBusMutex *) mutex); - } + if (mutex && thread_init_generation == _dbus_current_generation) + _dbus_platform_cmutex_unlock (mutex); } /** @@ -318,8 +256,8 @@ _dbus_cmutex_unlock (DBusCMutex *mutex) DBusCondVar * _dbus_condvar_new (void) { - if (thread_functions.condvar_new) - return (* thread_functions.condvar_new) (); + if (thread_init_generation == _dbus_current_generation) + return _dbus_platform_condvar_new (); else return _DBUS_DUMMY_CONDVAR; } @@ -338,15 +276,18 @@ _dbus_condvar_new (void) void _dbus_condvar_new_at_location (DBusCondVar **location_p) { - *location_p = _dbus_condvar_new(); + _dbus_assert (location_p != NULL); - if (thread_init_generation != _dbus_current_generation && *location_p) + if (thread_init_generation == _dbus_current_generation) + { + *location_p = _dbus_condvar_new(); + } + else { + *location_p = _DBUS_DUMMY_CONDVAR; + if (!_dbus_list_append (&uninitialized_condvar_list, location_p)) - { - _dbus_condvar_free (*location_p); - *location_p = NULL; - } + *location_p = NULL; } } @@ -358,8 +299,8 @@ _dbus_condvar_new_at_location (DBusCondVar **location_p) void _dbus_condvar_free (DBusCondVar *cond) { - if (cond && thread_functions.condvar_free) - (* thread_functions.condvar_free) (cond); + if (cond && thread_init_generation == _dbus_current_generation) + _dbus_platform_condvar_free (cond); } /** @@ -370,12 +311,19 @@ _dbus_condvar_free (DBusCondVar *cond) void _dbus_condvar_free_at_location (DBusCondVar **location_p) { - if (location_p) + if (location_p == NULL) + return; + + if (thread_init_generation == _dbus_current_generation) + { + if (*location_p != NULL) + _dbus_platform_condvar_free (*location_p); + } + else { - if (thread_init_generation != _dbus_current_generation) - _dbus_list_remove (&uninitialized_condvar_list, location_p); + _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_CONDVAR); - _dbus_condvar_free (*location_p); + _dbus_list_remove (&uninitialized_condvar_list, location_p); } } @@ -389,8 +337,8 @@ void _dbus_condvar_wait (DBusCondVar *cond, DBusCMutex *mutex) { - if (cond && mutex && thread_functions.condvar_wait) - (* thread_functions.condvar_wait) (cond, (DBusMutex *) mutex); + if (cond && mutex && thread_init_generation == _dbus_current_generation) + _dbus_platform_condvar_wait (cond, mutex); } /** @@ -409,10 +357,9 @@ _dbus_condvar_wait_timeout (DBusCondVar *cond, DBusCMutex *mutex, int timeout_milliseconds) { - if (cond && mutex && thread_functions.condvar_wait) - return (* thread_functions.condvar_wait_timeout) (cond, - (DBusMutex *) mutex, - timeout_milliseconds); + if (cond && mutex && thread_init_generation == _dbus_current_generation) + return _dbus_platform_condvar_wait_timeout (cond, mutex, + timeout_milliseconds); else return TRUE; } @@ -425,8 +372,8 @@ _dbus_condvar_wait_timeout (DBusCondVar *cond, void _dbus_condvar_wake_one (DBusCondVar *cond) { - if (cond && thread_functions.condvar_wake_one) - (* thread_functions.condvar_wake_one) (cond); + if (cond && thread_init_generation == _dbus_current_generation) + _dbus_platform_condvar_wake_one (cond); } /** @@ -437,20 +384,22 @@ _dbus_condvar_wake_one (DBusCondVar *cond) void _dbus_condvar_wake_all (DBusCondVar *cond) { - if (cond && thread_functions.condvar_wake_all) - (* thread_functions.condvar_wake_all) (cond); + if (cond && thread_init_generation == _dbus_current_generation) + _dbus_platform_condvar_wake_all (cond); } static void shutdown_global_locks (void *data) { - DBusMutex ***locks = data; + DBusRMutex ***locks = data; int i; i = 0; while (i < _DBUS_N_GLOBAL_LOCKS) { - _dbus_mutex_free (*(locks[i]), thread_functions.recursive_mutex_free); + if (*(locks[i]) != NULL) + _dbus_platform_rmutex_free (*(locks[i])); + *(locks[i]) = NULL; ++i; } @@ -476,12 +425,12 @@ init_uninitialized_locks (void) link = uninitialized_rmutex_list; while (link != NULL) { - DBusMutex **mp; + DBusRMutex **mp; mp = link->data; - _dbus_assert (*mp == _DBUS_DUMMY_MUTEX); + _dbus_assert (*mp == _DBUS_DUMMY_RMUTEX); - *mp = _dbus_mutex_new (thread_functions.recursive_mutex_new); + *mp = _dbus_platform_rmutex_new (); if (*mp == NULL) goto fail_mutex; @@ -491,12 +440,12 @@ init_uninitialized_locks (void) link = uninitialized_cmutex_list; while (link != NULL) { - DBusMutex **mp; + DBusCMutex **mp; mp = link->data; - _dbus_assert (*mp == _DBUS_DUMMY_MUTEX); + _dbus_assert (*mp == _DBUS_DUMMY_CMUTEX); - *mp = _dbus_mutex_new (thread_functions.mutex_new); + *mp = _dbus_platform_cmutex_new (); if (*mp == NULL) goto fail_mutex; @@ -511,7 +460,7 @@ init_uninitialized_locks (void) cp = (DBusCondVar **)link->data; _dbus_assert (*cp == _DBUS_DUMMY_CONDVAR); - *cp = _dbus_condvar_new (); + *cp = _dbus_platform_condvar_new (); if (*cp == NULL) goto fail_condvar; @@ -534,12 +483,10 @@ init_uninitialized_locks (void) { DBusCondVar **cp; - cp = (DBusCondVar **)link->data; + cp = link->data; - if (*cp != _DBUS_DUMMY_CONDVAR) - _dbus_condvar_free (*cp); - else - break; + if (*cp != _DBUS_DUMMY_CONDVAR && *cp != NULL) + _dbus_platform_condvar_free (*cp); *cp = _DBUS_DUMMY_CONDVAR; @@ -550,16 +497,14 @@ init_uninitialized_locks (void) link = uninitialized_rmutex_list; while (link != NULL) { - DBusMutex **mp; + DBusRMutex **mp; mp = link->data; - if (*mp != _DBUS_DUMMY_MUTEX) - _dbus_mutex_free (*mp, thread_functions.recursive_mutex_free); - else - break; + if (*mp != _DBUS_DUMMY_RMUTEX && *mp != NULL) + _dbus_platform_rmutex_free (*mp); - *mp = _DBUS_DUMMY_MUTEX; + *mp = _DBUS_DUMMY_RMUTEX; link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link); } @@ -567,16 +512,14 @@ init_uninitialized_locks (void) link = uninitialized_cmutex_list; while (link != NULL) { - DBusMutex **mp; + DBusCMutex **mp; mp = link->data; - if (*mp != _DBUS_DUMMY_MUTEX) - _dbus_mutex_free (*mp, thread_functions.mutex_free); - else - break; + if (*mp != _DBUS_DUMMY_CMUTEX && *mp != NULL) + _dbus_platform_cmutex_free (*mp); - *mp = _DBUS_DUMMY_MUTEX; + *mp = _DBUS_DUMMY_CMUTEX; link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link); } @@ -622,7 +565,7 @@ init_locks (void) while (i < _DBUS_N_ELEMENTS (global_locks)) { - *global_locks[i] = (DBusRMutex *) _dbus_mutex_new (thread_functions.recursive_mutex_new); + *global_locks[i] = _dbus_platform_rmutex_new (); if (*global_locks[i] == NULL) goto failed; @@ -646,8 +589,7 @@ init_locks (void) for (i = i - 1; i >= 0; i--) { - _dbus_mutex_free ((DBusMutex *) *global_locks[i], - thread_functions.recursive_mutex_free); + _dbus_platform_rmutex_free (*global_locks[i]); *global_locks[i] = NULL; } return FALSE; @@ -676,147 +618,19 @@ init_locks (void) */ /** - * - * Initializes threads. If this function is not called, the D-Bus - * library will not lock any data structures. If it is called, D-Bus - * will do locking, at some cost in efficiency. Note that this - * function must be called BEFORE the second thread is started. - * - * Almost always, you should use dbus_threads_init_default() instead. - * The raw dbus_threads_init() is only useful if you require a - * particular thread implementation for some reason. - * - * A possible reason to use dbus_threads_init() rather than - * dbus_threads_init_default() is to insert debugging checks or print - * statements. - * - * dbus_threads_init() may be called more than once. The first one - * wins and subsequent calls are ignored. (Unless you use - * dbus_shutdown() to reset libdbus, which will let you re-init - * threads.) - * - * Either recursive or nonrecursive mutex functions must be specified, - * but not both. New code should provide only the recursive functions - * - specifying the nonrecursive ones is deprecated. + * Initializes threads, like dbus_threads_init_default(). + * This version previously allowed user-specified threading + * primitives, but since D-Bus 1.6 it ignores them and behaves + * exactly like dbus_threads_init_default(). * - * Because this function effectively sets global state, all code - * running in a given application must agree on the thread - * implementation. Most code won't care which thread implementation is - * used, so there's no problem. However, usually libraries should not - * call dbus_threads_init() or dbus_threads_init_default(), instead - * leaving this policy choice to applications. - * - * The exception is for application frameworks (GLib, Qt, etc.) and - * D-Bus bindings based on application frameworks. These frameworks - * define a cross-platform thread abstraction and can assume - * applications using the framework are OK with using that thread - * abstraction. - * - * However, even these app frameworks may find it easier to simply call - * dbus_threads_init_default(), and there's no reason they shouldn't. - * - * @param functions functions for using threads + * @param functions ignored, formerly functions for using threads * @returns #TRUE on success, #FALSE if no memory */ dbus_bool_t dbus_threads_init (const DBusThreadFunctions *functions) { - dbus_bool_t mutex_set; - dbus_bool_t recursive_mutex_set; - - _dbus_assert (functions != NULL); - - /* these base functions are required. Future additions to - * DBusThreadFunctions may be optional. - */ - _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK); - _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK); - _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK); - _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK); - _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK); - _dbus_assert (functions->mask & DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK); - _dbus_assert (functions->condvar_new != NULL); - _dbus_assert (functions->condvar_free != NULL); - _dbus_assert (functions->condvar_wait != NULL); - _dbus_assert (functions->condvar_wait_timeout != NULL); - _dbus_assert (functions->condvar_wake_one != NULL); - _dbus_assert (functions->condvar_wake_all != NULL); - - /* Either the mutex function set or recursive mutex set needs - * to be available but not both - */ - mutex_set = (functions->mask & DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK) && - (functions->mask & DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK) && - (functions->mask & DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK) && - (functions->mask & DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK) && - functions->mutex_new && - functions->mutex_free && - functions->mutex_lock && - functions->mutex_unlock; - - recursive_mutex_set = - (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK) && - (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK) && - (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK) && - (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK) && - functions->recursive_mutex_new && - functions->recursive_mutex_free && - functions->recursive_mutex_lock && - functions->recursive_mutex_unlock; - - if (!(mutex_set || recursive_mutex_set)) - _dbus_assert_not_reached ("Either the nonrecusrive or recursive mutex " - "functions sets should be passed into " - "dbus_threads_init. Neither sets were passed."); - - /* Check that all bits in the mask actually are valid mask bits. - * ensures people won't write code that breaks when we add - * new bits. - */ - _dbus_assert ((functions->mask & ~DBUS_THREAD_FUNCTIONS_ALL_MASK) == 0); - - if (thread_init_generation != _dbus_current_generation) - thread_functions.mask = 0; /* allow re-init in new generation */ - - /* Silently allow multiple init - * First init wins and D-Bus will always use its threading system - */ - if (thread_functions.mask != 0) + if (thread_init_generation == _dbus_current_generation) return TRUE; - - thread_functions.mutex_new = functions->mutex_new; - thread_functions.mutex_free = functions->mutex_free; - thread_functions.mutex_lock = functions->mutex_lock; - thread_functions.mutex_unlock = functions->mutex_unlock; - - thread_functions.condvar_new = functions->condvar_new; - thread_functions.condvar_free = functions->condvar_free; - thread_functions.condvar_wait = functions->condvar_wait; - thread_functions.condvar_wait_timeout = functions->condvar_wait_timeout; - thread_functions.condvar_wake_one = functions->condvar_wake_one; - thread_functions.condvar_wake_all = functions->condvar_wake_all; - - if (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK) - thread_functions.recursive_mutex_new = functions->recursive_mutex_new; - else - thread_functions.recursive_mutex_new = NULL; - - if (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK) - thread_functions.recursive_mutex_free = functions->recursive_mutex_free; - else - thread_functions.recursive_mutex_free = NULL; - - if (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK) - thread_functions.recursive_mutex_lock = functions->recursive_mutex_lock; - else - thread_functions.recursive_mutex_lock = NULL; - - if (functions->mask & DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK) - thread_functions.recursive_mutex_unlock = functions->recursive_mutex_unlock; - else - thread_functions.recursive_mutex_unlock = NULL; - - thread_functions.mask = functions->mask; if (!init_locks ()) return FALSE; @@ -831,11 +645,10 @@ dbus_threads_init (const DBusThreadFunctions *functions) /* Default thread implemenation */ /** - * - * Calls dbus_threads_init() with a default set of - * #DBusThreadFunctions appropriate for the platform. - * - * Most applications should use this rather than dbus_threads_init(). + * Initializes threads. If this function is not called, the D-Bus + * library will not lock any data structures. If it is called, D-Bus + * will do locking, at some cost in efficiency. Note that this + * function must be called BEFORE the second thread is started. * * It's safe to call dbus_threads_init_default() as many times as you * want, but only the first time will have an effect. @@ -855,144 +668,11 @@ dbus_threads_init_default (void) /** @} */ #ifdef DBUS_BUILD_TESTS -/** Fake mutex used for debugging */ -typedef struct DBusFakeMutex DBusFakeMutex; -/** Fake mutex used for debugging */ -struct DBusFakeMutex -{ - dbus_bool_t locked; /**< Mutex is "locked" */ -}; - -static DBusMutex * dbus_fake_mutex_new (void); -static void dbus_fake_mutex_free (DBusMutex *mutex); -static dbus_bool_t dbus_fake_mutex_lock (DBusMutex *mutex); -static dbus_bool_t dbus_fake_mutex_unlock (DBusMutex *mutex); -static DBusCondVar* dbus_fake_condvar_new (void); -static void dbus_fake_condvar_free (DBusCondVar *cond); -static void dbus_fake_condvar_wait (DBusCondVar *cond, - DBusMutex *mutex); -static dbus_bool_t dbus_fake_condvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, - int timeout_msec); -static void dbus_fake_condvar_wake_one (DBusCondVar *cond); -static void dbus_fake_condvar_wake_all (DBusCondVar *cond); - - -static const DBusThreadFunctions fake_functions = -{ - DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK | - DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK | - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK| - DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK, - dbus_fake_mutex_new, - dbus_fake_mutex_free, - dbus_fake_mutex_lock, - dbus_fake_mutex_unlock, - dbus_fake_condvar_new, - dbus_fake_condvar_free, - dbus_fake_condvar_wait, - dbus_fake_condvar_wait_timeout, - dbus_fake_condvar_wake_one, - dbus_fake_condvar_wake_all -}; - -static DBusMutex * -dbus_fake_mutex_new (void) -{ - DBusFakeMutex *mutex; - - mutex = dbus_new0 (DBusFakeMutex, 1); - - return (DBusMutex *)mutex; -} - -static void -dbus_fake_mutex_free (DBusMutex *mutex) -{ - DBusFakeMutex *fake = (DBusFakeMutex*) mutex; - - _dbus_assert (!fake->locked); - - dbus_free (fake); -} - -static dbus_bool_t -dbus_fake_mutex_lock (DBusMutex *mutex) -{ - DBusFakeMutex *fake = (DBusFakeMutex*) mutex; - - _dbus_assert (!fake->locked); - - fake->locked = TRUE; - - return TRUE; -} - -static dbus_bool_t -dbus_fake_mutex_unlock (DBusMutex *mutex) -{ - DBusFakeMutex *fake = (DBusFakeMutex*) mutex; - - _dbus_assert (fake->locked); - - fake->locked = FALSE; - - return TRUE; -} - -static DBusCondVar* -dbus_fake_condvar_new (void) -{ - return (DBusCondVar*) _dbus_strdup ("FakeCondvar"); -} - -static void -dbus_fake_condvar_free (DBusCondVar *cond) -{ - dbus_free (cond); -} - -static void -dbus_fake_condvar_wait (DBusCondVar *cond, - DBusMutex *mutex) -{ - -} - -static dbus_bool_t -dbus_fake_condvar_wait_timeout (DBusCondVar *cond, - DBusMutex *mutex, - int timeout_msec) -{ - return TRUE; -} - -static void -dbus_fake_condvar_wake_one (DBusCondVar *cond) -{ - -} - -static void -dbus_fake_condvar_wake_all (DBusCondVar *cond) -{ - -} dbus_bool_t _dbus_threads_init_debug (void) { -#ifdef DBUS_WIN return _dbus_threads_init_platform_specific(); -#else - return dbus_threads_init (&fake_functions); -#endif } #endif /* DBUS_BUILD_TESTS */ -- 1.7.9