Never use non-libdbus threading primitives
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Mon, 20 Feb 2012 15:20:41 +0000 (15:20 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 21 Feb 2012 14:41:40 +0000 (14:41 +0000)
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
Reviewed-by: Thiago Macieira <thiago@kde.org>
dbus/dbus-sysdeps-pthread.c
dbus/dbus-sysdeps-thread-win.c
dbus/dbus-threads-internal.h
dbus/dbus-threads.c

index 062b53e..9758934 100644 (file)
  */
 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);
 }
index e2972a3..db48619 100644 (file)
@@ -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);
 }
 
index 2561136..680a603 100644 (file)
@@ -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 */
index 02b4199..df00783 100644 (file)
 #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,19 +34,12 @@ 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)
 
-static void _dbus_mutex_free (DBusMutex *mutex, DBusMutexFreeFunction dtor);
-static void _dbus_mutex_new_at_location (DBusMutex            **location_p,
-                                         DBusMutexNewFunction   ctor,
-                                         DBusMutexFreeFunction  dtor,
-                                         DBusList             **uninitialized);
-static void _dbus_mutex_free_at_location (DBusMutex            **location_p,
-                                          DBusMutexFreeFunction  dtor,
-                                          DBusList             **uninitialized);
-
 /**
  * @defgroup DBusThreadsInternals Thread functions
  * @ingroup  DBusInternals
@@ -67,30 +50,8 @@ 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
- */
-static DBusMutex *
-_dbus_mutex_new (DBusMutexNewFunction ctor)
-{
-  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) ();
-  else
-    return _DBUS_DUMMY_MUTEX;
-}
-
 /**
- * Creates a new mutex using the function supplied to dbus_threads_init(),
+ * Creates a new mutex
  * or creates a no-op mutex if threads are not initialized.
  * May return #NULL even if threads are initialized, indicating
  * out-of-memory.
@@ -108,14 +69,23 @@ _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;
+    }
 }
 
 /**
- * Creates a new mutex using the function supplied to dbus_threads_init(),
+ * Creates a new mutex
  * or creates a no-op mutex if threads are not initialized.
  * May return #NULL even if threads are initialized, indicating
  * out-of-memory.
@@ -132,98 +102,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 (!_dbus_list_append (uninitialized, location_p))
-        {
-         _dbus_mutex_free (*location_p, dtor);
-         *location_p = NULL;
-       }
-    }
-}
-
-/*
- * 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 (thread_init_generation == _dbus_current_generation)
     {
-      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);
+      *location_p = _dbus_platform_cmutex_new ();
     }
-}
-
-/*
- * 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 +148,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 +172,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 +184,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 +196,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 +208,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 +223,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 +243,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 +266,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 +278,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 (thread_init_generation != _dbus_current_generation)
-        _dbus_list_remove (&uninitialized_condvar_list, location_p);
+      if (*location_p != NULL)
+        _dbus_platform_condvar_free (*location_p);
+    }
+  else
+    {
+      _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 +304,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 +324,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 +339,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 +351,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 +392,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 +407,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 +427,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 +450,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 +464,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 +479,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 +532,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 +556,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 +585,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.
+ * 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().
  *
- * 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.
- *
- * 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 +612,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 +635,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 */