ListNames and ListQueuedOwners updated to work with new kdbus
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-thread-win.c
index 4c4d22f..0887a54 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 
+#include <config.h>
 #include "dbus-internals.h"
 #include "dbus-sysdeps.h"
 #include "dbus-sysdeps-win.h"
 
 #include <windows.h>
 
+static dbus_bool_t global_init_done = FALSE;
+static CRITICAL_SECTION init_lock;
+
+/* Called from C++ code in dbus-init-win.cpp. */
+void
+_dbus_threads_windows_init_global (void)
+{
+  /* this ensures that the object that acts as our global constructor
+   * actually gets linked in when we're linked statically */
+  _dbus_threads_windows_ensure_ctor_linked ();
+
+  InitializeCriticalSection (&init_lock);
+  global_init_done = TRUE;
+}
+
 struct DBusCondVar {
   DBusList *list;        /**< list thread-local-stored events waiting on the cond variable */
   CRITICAL_SECTION lock; /**< lock protecting the list */
@@ -45,13 +61,17 @@ _dbus_win_get_dll_hmodule (void)
   return dbus_dll_hmodule;
 }
 
-BOOL WINAPI DllMain (HINSTANCE hinstDLL,
-                    DWORD     fdwReason,
-                    LPVOID    lpvReserved);
+#ifdef DBUS_WINCE
+#define hinst_t HANDLE
+#else
+#define hinst_t HINSTANCE
+#endif
+
+BOOL WINAPI DllMain (hinst_t, DWORD, LPVOID);
 
 /* We need this to free the TLS events on thread exit */
 BOOL WINAPI
-DllMain (HINSTANCE hinstDLL,
+DllMain (hinst_t hinstDLL,
         DWORD     fdwReason,
         LPVOID    lpvReserved)
 {
@@ -85,34 +105,60 @@ DllMain (HINSTANCE hinstDLL,
   return TRUE;
 }
 
-static DBusMutex*
-_dbus_windows_mutex_new (void)
+DBusCMutex *
+_dbus_platform_cmutex_new (void)
+{
+  HANDLE handle;
+  handle = CreateMutex (NULL, FALSE, NULL);
+  return (DBusCMutex *) handle;
+}
+
+DBusRMutex *
+_dbus_platform_rmutex_new (void)
 {
   HANDLE handle;
   handle = CreateMutex (NULL, FALSE, NULL);
-  return (DBusMutex *) handle;
+  return (DBusRMutex *) handle;
 }
 
-static void
-_dbus_windows_mutex_free (DBusMutex *mutex)
+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)
+{
+  WaitForSingleObject ((HANDLE *) mutex, INFINITE);
+}
+
+void
+_dbus_platform_cmutex_unlock (DBusCMutex *mutex)
+{
+  ReleaseMutex ((HANDLE *) mutex);
+}
+
+void
+_dbus_platform_rmutex_unlock (DBusRMutex *mutex)
 {
-  return ReleaseMutex ((HANDLE *) mutex) != 0;
+  ReleaseMutex ((HANDLE *) mutex);
 }
 
-static DBusCondVar *
-_dbus_windows_condvar_new (void)
+DBusCondVar *
+_dbus_platform_condvar_new (void)
 {
   DBusCondVar *cond;
     
@@ -123,11 +169,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);
@@ -136,7 +182,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;
@@ -163,9 +209,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)
     {
@@ -193,67 +239,38 @@ _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);
   
   if (cond->list != NULL)
-    SetEvent (_dbus_list_pop_first (&cond->list));
-    
-  LeaveCriticalSection (&cond->lock);
-}
-
-static void
-_dbus_windows_condvar_wake_all (DBusCondVar *cond)
-{
-  EnterCriticalSection (&cond->lock);
-
-  while (cond->list != NULL)
-    SetEvent (_dbus_list_pop_first (&cond->list));
-  
+    {
+      SetEvent (_dbus_list_pop_first (&cond->list));
+      /* Avoid live lock by pushing the waiter to the mutex lock
+         instruction, which is fair.  If we don't do this, we could
+         acquire the condition variable again before the waiter has a
+         chance itself, leading to starvation.  */
+      Sleep (0);
+    }
   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)
 {
@@ -267,6 +284,19 @@ _dbus_threads_init_platform_specific (void)
        return FALSE;
     }
 
-  return dbus_threads_init (&windows_functions);
+  return TRUE;
 }
 
+void
+_dbus_threads_lock_platform_specific (void)
+{
+  _dbus_assert (global_init_done);
+  EnterCriticalSection (&init_lock);
+}
+
+void
+_dbus_threads_unlock_platform_specific (void)
+{
+  _dbus_assert (global_init_done);
+  LeaveCriticalSection (&init_lock);
+}