00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-internals.h"
00026 #include "dbus-sysdeps.h"
00027 #include "dbus-sysdeps-win.h"
00028 #include "dbus-threads.h"
00029 #include "dbus-list.h"
00030
00031 #include <windows.h>
00032
00033 struct DBusCondVar {
00034 DBusList *list;
00035 CRITICAL_SECTION lock;
00036 };
00037
00038 static DWORD dbus_cond_event_tls = TLS_OUT_OF_INDEXES;
00039
00040
00041 static HMODULE dbus_dll_hmodule;
00042
00043 void *
00044 _dbus_win_get_dll_hmodule (void)
00045 {
00046 return dbus_dll_hmodule;
00047 }
00048
00049 #ifdef DBUS_WINCE
00050 #define hinst_t HANDLE
00051 #else
00052 #define hinst_t HINSTANCE
00053 #endif
00054
00055 BOOL WINAPI DllMain (hinst_t, DWORD, LPVOID);
00056
00057
00058 BOOL WINAPI
00059 DllMain (hinst_t hinstDLL,
00060 DWORD fdwReason,
00061 LPVOID lpvReserved)
00062 {
00063 HANDLE event;
00064 switch (fdwReason)
00065 {
00066 case DLL_PROCESS_ATTACH:
00067 dbus_dll_hmodule = hinstDLL;
00068 break;
00069 case DLL_THREAD_DETACH:
00070 if (dbus_cond_event_tls != TLS_OUT_OF_INDEXES)
00071 {
00072 event = TlsGetValue(dbus_cond_event_tls);
00073 CloseHandle (event);
00074 TlsSetValue(dbus_cond_event_tls, NULL);
00075 }
00076 break;
00077 case DLL_PROCESS_DETACH:
00078 if (dbus_cond_event_tls != TLS_OUT_OF_INDEXES)
00079 {
00080 event = TlsGetValue(dbus_cond_event_tls);
00081 CloseHandle (event);
00082 TlsSetValue(dbus_cond_event_tls, NULL);
00083
00084 TlsFree(dbus_cond_event_tls);
00085 }
00086 break;
00087 default:
00088 break;
00089 }
00090 return TRUE;
00091 }
00092
00093 DBusCMutex *
00094 _dbus_platform_cmutex_new (void)
00095 {
00096 HANDLE handle;
00097 handle = CreateMutex (NULL, FALSE, NULL);
00098 return (DBusCMutex *) handle;
00099 }
00100
00101 DBusRMutex *
00102 _dbus_platform_rmutex_new (void)
00103 {
00104 HANDLE handle;
00105 handle = CreateMutex (NULL, FALSE, NULL);
00106 return (DBusRMutex *) handle;
00107 }
00108
00109 void
00110 _dbus_platform_cmutex_free (DBusCMutex *mutex)
00111 {
00112 CloseHandle ((HANDLE *) mutex);
00113 }
00114
00115 void
00116 _dbus_platform_rmutex_free (DBusRMutex *mutex)
00117 {
00118 CloseHandle ((HANDLE *) mutex);
00119 }
00120
00121 void
00122 _dbus_platform_cmutex_lock (DBusCMutex *mutex)
00123 {
00124 WaitForSingleObject ((HANDLE *) mutex, INFINITE);
00125 }
00126
00127 void
00128 _dbus_platform_rmutex_lock (DBusRMutex *mutex)
00129 {
00130 WaitForSingleObject ((HANDLE *) mutex, INFINITE);
00131 }
00132
00133 void
00134 _dbus_platform_cmutex_unlock (DBusCMutex *mutex)
00135 {
00136 ReleaseMutex ((HANDLE *) mutex);
00137 }
00138
00139 void
00140 _dbus_platform_rmutex_unlock (DBusRMutex *mutex)
00141 {
00142 ReleaseMutex ((HANDLE *) mutex);
00143 }
00144
00145 DBusCondVar *
00146 _dbus_platform_condvar_new (void)
00147 {
00148 DBusCondVar *cond;
00149
00150 cond = dbus_new (DBusCondVar, 1);
00151 if (cond == NULL)
00152 return NULL;
00153
00154 cond->list = NULL;
00155
00156 InitializeCriticalSection (&cond->lock);
00157 return cond;
00158 }
00159
00160 void
00161 _dbus_platform_condvar_free (DBusCondVar *cond)
00162 {
00163 DeleteCriticalSection (&cond->lock);
00164 _dbus_list_clear (&cond->list);
00165 dbus_free (cond);
00166 }
00167
00168 static dbus_bool_t
00169 _dbus_condvar_wait_win32 (DBusCondVar *cond,
00170 DBusCMutex *mutex,
00171 int milliseconds)
00172 {
00173 DWORD retval;
00174 dbus_bool_t ret;
00175 HANDLE event = TlsGetValue (dbus_cond_event_tls);
00176
00177 if (!event)
00178 {
00179 event = CreateEvent (0, FALSE, FALSE, NULL);
00180 if (event == 0)
00181 return FALSE;
00182 TlsSetValue (dbus_cond_event_tls, event);
00183 }
00184
00185 EnterCriticalSection (&cond->lock);
00186
00187
00188 _dbus_assert (WaitForSingleObject (event, 0) == WAIT_TIMEOUT);
00189
00190 ret = _dbus_list_append (&cond->list, event);
00191
00192 LeaveCriticalSection (&cond->lock);
00193
00194 if (!ret)
00195 return FALSE;
00196
00197 _dbus_platform_cmutex_unlock (mutex);
00198 retval = WaitForSingleObject (event, milliseconds);
00199 _dbus_platform_cmutex_lock (mutex);
00200
00201 if (retval == WAIT_TIMEOUT)
00202 {
00203 EnterCriticalSection (&cond->lock);
00204 _dbus_list_remove (&cond->list, event);
00205
00206
00207
00208
00209
00210 retval = WaitForSingleObject (event, 0);
00211
00212 LeaveCriticalSection (&cond->lock);
00213 }
00214
00215 #ifndef DBUS_DISABLE_ASSERT
00216 EnterCriticalSection (&cond->lock);
00217
00218
00219 _dbus_assert (_dbus_list_remove (&cond->list, event) == FALSE);
00220
00221 LeaveCriticalSection (&cond->lock);
00222 #endif
00223
00224 return retval != WAIT_TIMEOUT;
00225 }
00226
00227 void
00228 _dbus_platform_condvar_wait (DBusCondVar *cond,
00229 DBusCMutex *mutex)
00230 {
00231 _dbus_condvar_wait_win32 (cond, mutex, INFINITE);
00232 }
00233
00234 dbus_bool_t
00235 _dbus_platform_condvar_wait_timeout (DBusCondVar *cond,
00236 DBusCMutex *mutex,
00237 int timeout_milliseconds)
00238 {
00239 return _dbus_condvar_wait_win32 (cond, mutex, timeout_milliseconds);
00240 }
00241
00242 void
00243 _dbus_platform_condvar_wake_one (DBusCondVar *cond)
00244 {
00245 EnterCriticalSection (&cond->lock);
00246
00247 if (cond->list != NULL)
00248 {
00249 SetEvent (_dbus_list_pop_first (&cond->list));
00250
00251
00252
00253
00254 Sleep (0);
00255 }
00256 LeaveCriticalSection (&cond->lock);
00257 }
00258
00259 dbus_bool_t
00260 _dbus_threads_init_platform_specific (void)
00261 {
00262
00263
00264
00265 if (dbus_cond_event_tls == TLS_OUT_OF_INDEXES)
00266 {
00267 dbus_cond_event_tls = TlsAlloc ();
00268 if (dbus_cond_event_tls == TLS_OUT_OF_INDEXES)
00269 return FALSE;
00270 }
00271
00272 return dbus_threads_init (NULL);
00273 }
00274