diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2018-05-29 16:07:48 +0000 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2018-05-29 16:07:48 +0000 |
commit | 42a9e80ab13879af02e913367ca653366fcf57f6 (patch) | |
tree | 10e6cdb07431da1c7bac0a66b7e7114af32b0301 | |
parent | 6054d1100196166e234925bc46bab1256089051e (diff) | |
parent | a2aa91ae5d263eb00e440680262155b755077114 (diff) | |
download | glib-42a9e80ab13879af02e913367ca653366fcf57f6.tar.gz |
Merge branch 'remove-winxp-comapt-code' into 'master'
Remove winxp compat code
See merge request GNOME/glib!41
-rw-r--r-- | gio/ginetaddress.c | 92 | ||||
-rw-r--r-- | glib/gmessages.c | 68 | ||||
-rw-r--r-- | glib/gthread-win32.c | 564 |
3 files changed, 16 insertions, 708 deletions
diff --git a/gio/ginetaddress.c b/gio/ginetaddress.c index 0a0a85a48..787c757da 100644 --- a/gio/ginetaddress.c +++ b/gio/ginetaddress.c @@ -376,98 +376,6 @@ g_inet_address_init (GInetAddress *address) address->priv = g_inet_address_get_instance_private (address); } -/* These are provided so that we can use inet_pton() and inet_ntop() on Windows - * if they are available (i.e. Vista and later), and use the existing code path - * on Windows XP/Server 2003. We can drop this portion when we drop support for - * XP/Server 2003. - */ -#if defined(G_OS_WIN32) && _WIN32_WINNT < 0x0600 -static gint -inet_pton (gint family, - const gchar *addr_string, - gpointer addr) -{ - /* For Vista/Server 2008 and later, there is native inet_pton() in Winsock2 */ - if (ws2funcs.pInetPton != NULL) - return ws2funcs.pInetPton (family, addr_string, addr); - else - { - /* Fallback codepath for XP/Server 2003 */ - struct sockaddr_storage sa; - struct sockaddr_in *sin = (struct sockaddr_in *)&sa; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa; - gint len = sizeof (sa); - - if (family != AF_INET && family != AF_INET6) - { - WSASetLastError (WSAEAFNOSUPPORT); - return -1; - } - - /* WSAStringToAddress() will accept various not-an-IP-address - * strings like "127.0.0.1:80", "[1234::5678]:80", "127.1", etc. - */ - if (!g_hostname_is_ip_address (addr_string)) - return 0; - - if (WSAStringToAddress ((LPTSTR) addr_string, family, NULL, (LPSOCKADDR) &sa, &len) != 0) - return 0; - - if (family == AF_INET) - *(IN_ADDR *)addr = sin->sin_addr; - else - *(IN6_ADDR *)addr = sin6->sin6_addr; - - return 1; - } -} - -static const gchar * -inet_ntop (gint family, - const gpointer addr, - gchar *addr_str, - socklen_t size) -{ - /* On Vista/Server 2008 and later, there is native inet_ntop() in Winsock2 */ - if (ws2funcs.pInetNtop != NULL) - return ws2funcs.pInetNtop (family, addr, addr_str, size); - else - { - /* Fallback codepath for XP/Server 2003 */ - DWORD buflen = size, addrlen; - struct sockaddr_storage sa; - struct sockaddr_in *sin = (struct sockaddr_in *)&sa; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa; - - memset (&sa, 0, sizeof (sa)); - sa.ss_family = family; - if (sa.ss_family == AF_INET) - { - struct in_addr *addrv4 = (struct in_addr *) addr; - - addrlen = sizeof (*sin); - memcpy (&sin->sin_addr, addrv4, sizeof (sin->sin_addr)); - } - else if (sa.ss_family == AF_INET6) - { - struct in6_addr *addrv6 = (struct in6_addr *) addr; - - addrlen = sizeof (*sin6); - memcpy (&sin6->sin6_addr, addrv6, sizeof (sin6->sin6_addr)); - } - else - { - WSASetLastError (WSAEAFNOSUPPORT); - return NULL; - } - if (WSAAddressToString ((LPSOCKADDR) &sa, addrlen, NULL, addr_str, &buflen) == 0) - return addr_str; - else - return NULL; - } -} -#endif - /** * g_inet_address_new_from_string: * @string: a string representation of an IP address diff --git a/glib/gmessages.c b/glib/gmessages.c index eaca78387..b468ef3b7 100644 --- a/glib/gmessages.c +++ b/glib/gmessages.c @@ -211,47 +211,6 @@ #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif -/* XXX: Remove once XP support really dropped */ -#if _WIN32_WINNT < 0x0600 - -typedef enum _FILE_INFO_BY_HANDLE_CLASS -{ - FileBasicInfo = 0, - FileStandardInfo = 1, - FileNameInfo = 2, - FileRenameInfo = 3, - FileDispositionInfo = 4, - FileAllocationInfo = 5, - FileEndOfFileInfo = 6, - FileStreamInfo = 7, - FileCompressionInfo = 8, - FileAttributeTagInfo = 9, - FileIdBothDirectoryInfo = 10, - FileIdBothDirectoryRestartInfo = 11, - FileIoPriorityHintInfo = 12, - FileRemoteProtocolInfo = 13, - FileFullDirectoryInfo = 14, - FileFullDirectoryRestartInfo = 15, - FileStorageInfo = 16, - FileAlignmentInfo = 17, - FileIdInfo = 18, - FileIdExtdDirectoryInfo = 19, - FileIdExtdDirectoryRestartInfo = 20, - MaximumFileInfoByHandlesClass -} FILE_INFO_BY_HANDLE_CLASS; - -typedef struct _FILE_NAME_INFO -{ - DWORD FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFO; - -typedef BOOL (WINAPI fGetFileInformationByHandleEx) (HANDLE, - FILE_INFO_BY_HANDLE_CLASS, - LPVOID, - DWORD); -#endif - #if defined (_MSC_VER) && (_MSC_VER >=1400) /* This is ugly, but we need it for isatty() in case we have bad fd's, * otherwise Windows will abort() the program on msvcrt80.dll and later @@ -1539,34 +1498,13 @@ win32_is_pipe_tty (int fd) wchar_t *name = NULL; gint length; - /* XXX: Remove once XP support really dropped */ -#if _WIN32_WINNT < 0x0600 - HANDLE h_kerneldll = NULL; - fGetFileInformationByHandleEx *GetFileInformationByHandleEx; -#endif - h_fd = (HANDLE) _get_osfhandle (fd); if (h_fd == INVALID_HANDLE_VALUE || GetFileType (h_fd) != FILE_TYPE_PIPE) goto done_query; - /* The following check is available on Vista or later, so on XP, no color support */ /* mintty uses a pipe, in the form of \{cygwin|msys}-xxxxxxxxxxxxxxxx-ptyN-{from|to}-master */ - /* XXX: Remove once XP support really dropped */ -#if _WIN32_WINNT < 0x0600 - h_kerneldll = LoadLibraryW (L"kernel32.dll"); - - if (h_kerneldll == NULL) - goto done_query; - - GetFileInformationByHandleEx = - (fGetFileInformationByHandleEx *) GetProcAddress (h_kerneldll, "GetFileInformationByHandleEx"); - - if (GetFileInformationByHandleEx == NULL) - goto done_query; -#endif - info = g_try_malloc (info_size); if (info == NULL || @@ -1614,12 +1552,6 @@ done_query: if (info != NULL) g_free (info); - /* XXX: Remove once XP support really dropped */ -#if _WIN32_WINNT < 0x0600 - if (h_kerneldll != NULL) - FreeLibrary (h_kerneldll); -#endif - return result; } #endif diff --git a/glib/gthread-win32.c b/glib/gthread-win32.c index a81f00a5c..1ad5ece80 100644 --- a/glib/gthread-win32.c +++ b/glib/gthread-win32.c @@ -73,81 +73,36 @@ g_thread_abort (gint status, * of these new types is that they can be statically initialised to * zero. That means that they are completely ABI compatible with our * GMutex and GCond APIs. - * - * Unfortunately, Windows XP lacks these facilities and GLib still - * needs to support Windows XP. Our approach here is as follows: - * - * - avoid depending on structure declarations at compile-time by - * declaring our own GMutex and GCond strutures to be - * ABI-compatible with SRWLock and CONDITION_VARIABLE and using - * those instead - * - * - avoid a hard dependency on the symbols used to manipulate these - * structures by doing a dynamic lookup of those symbols at - * runtime - * - * - if the symbols are not available, emulate them using other - * primatives - * - * Using this approach also allows us to easily build a GLib that lacks - * support for Windows XP or to remove this code entirely when XP is no - * longer supported (end of line is currently April 8, 2014). */ -typedef struct -{ - void (__stdcall * CallThisOnThreadExit) (void); /* fake */ - - void (__stdcall * InitializeSRWLock) (gpointer lock); - void (__stdcall * DeleteSRWLock) (gpointer lock); /* fake */ - void (__stdcall * AcquireSRWLockExclusive) (gpointer lock); - BOOLEAN (__stdcall * TryAcquireSRWLockExclusive) (gpointer lock); - void (__stdcall * ReleaseSRWLockExclusive) (gpointer lock); - void (__stdcall * AcquireSRWLockShared) (gpointer lock); - BOOLEAN (__stdcall * TryAcquireSRWLockShared) (gpointer lock); - void (__stdcall * ReleaseSRWLockShared) (gpointer lock); - - void (__stdcall * InitializeConditionVariable) (gpointer cond); - void (__stdcall * DeleteConditionVariable) (gpointer cond); /* fake */ - BOOL (__stdcall * SleepConditionVariableSRW) (gpointer cond, - gpointer lock, - DWORD timeout, - ULONG flags); - void (__stdcall * WakeAllConditionVariable) (gpointer cond); - void (__stdcall * WakeConditionVariable) (gpointer cond); -} GThreadImplVtable; - -static GThreadImplVtable g_thread_impl_vtable; /* {{{1 GMutex */ void g_mutex_init (GMutex *mutex) { - g_thread_impl_vtable.InitializeSRWLock (mutex); + InitializeSRWLock ((gpointer) mutex); } void g_mutex_clear (GMutex *mutex) { - if (g_thread_impl_vtable.DeleteSRWLock != NULL) - g_thread_impl_vtable.DeleteSRWLock (mutex); } void g_mutex_lock (GMutex *mutex) { - g_thread_impl_vtable.AcquireSRWLockExclusive (mutex); + AcquireSRWLockExclusive ((gpointer) mutex); } gboolean g_mutex_trylock (GMutex *mutex) { - return g_thread_impl_vtable.TryAcquireSRWLockExclusive (mutex); + return TryAcquireSRWLockExclusive ((gpointer) mutex); } void g_mutex_unlock (GMutex *mutex) { - g_thread_impl_vtable.ReleaseSRWLockExclusive (mutex); + ReleaseSRWLockExclusive ((gpointer) mutex); } /* {{{1 GRecMutex */ @@ -221,83 +176,79 @@ g_rec_mutex_trylock (GRecMutex *mutex) void g_rw_lock_init (GRWLock *lock) { - g_thread_impl_vtable.InitializeSRWLock (lock); + InitializeSRWLock ((gpointer) lock); } void g_rw_lock_clear (GRWLock *lock) { - if (g_thread_impl_vtable.DeleteSRWLock != NULL) - g_thread_impl_vtable.DeleteSRWLock (lock); } void g_rw_lock_writer_lock (GRWLock *lock) { - g_thread_impl_vtable.AcquireSRWLockExclusive (lock); + AcquireSRWLockExclusive ((gpointer) lock); } gboolean g_rw_lock_writer_trylock (GRWLock *lock) { - return g_thread_impl_vtable.TryAcquireSRWLockExclusive (lock); + return TryAcquireSRWLockExclusive ((gpointer) lock); } void g_rw_lock_writer_unlock (GRWLock *lock) { - g_thread_impl_vtable.ReleaseSRWLockExclusive (lock); + ReleaseSRWLockExclusive ((gpointer) lock); } void g_rw_lock_reader_lock (GRWLock *lock) { - g_thread_impl_vtable.AcquireSRWLockShared (lock); + AcquireSRWLockShared ((gpointer) lock); } gboolean g_rw_lock_reader_trylock (GRWLock *lock) { - return g_thread_impl_vtable.TryAcquireSRWLockShared (lock); + return TryAcquireSRWLockShared ((gpointer) lock); } void g_rw_lock_reader_unlock (GRWLock *lock) { - g_thread_impl_vtable.ReleaseSRWLockShared (lock); + ReleaseSRWLockShared ((gpointer) lock); } /* {{{1 GCond */ void g_cond_init (GCond *cond) { - g_thread_impl_vtable.InitializeConditionVariable (cond); + InitializeConditionVariable ((gpointer) cond); } void g_cond_clear (GCond *cond) { - if (g_thread_impl_vtable.DeleteConditionVariable) - g_thread_impl_vtable.DeleteConditionVariable (cond); } void g_cond_signal (GCond *cond) { - g_thread_impl_vtable.WakeConditionVariable (cond); + WakeConditionVariable ((gpointer) cond); } void g_cond_broadcast (GCond *cond) { - g_thread_impl_vtable.WakeAllConditionVariable (cond); + WakeAllConditionVariable ((gpointer) cond); } void g_cond_wait (GCond *cond, GMutex *entered_mutex) { - g_thread_impl_vtable.SleepConditionVariableSRW (cond, entered_mutex, INFINITE, 0); + SleepConditionVariableSRW ((gpointer) cond, (gpointer) entered_mutex, INFINITE, 0); } gboolean @@ -326,7 +277,7 @@ g_cond_wait_until (GCond *cond, if (span_millis >= INFINITE) span_millis = INFINITE - 1; - signalled = g_thread_impl_vtable.SleepConditionVariableSRW (cond, entered_mutex, span_millis, 0); + signalled = SleepConditionVariableSRW ((gpointer) cond, (gpointer) entered_mutex, span_millis, 0); if (signalled) break; @@ -580,491 +531,11 @@ g_system_thread_set_name (const gchar *name) SetThreadName ((DWORD) -1, name); } -/* {{{1 SRWLock and CONDITION_VARIABLE emulation (for Windows XP) */ - -static CRITICAL_SECTION g_thread_xp_lock; -static DWORD g_thread_xp_waiter_tls; - -/* {{{2 GThreadWaiter utility class for CONDITION_VARIABLE emulation */ -typedef struct _GThreadXpWaiter GThreadXpWaiter; -struct _GThreadXpWaiter -{ - HANDLE event; - volatile GThreadXpWaiter *next; - volatile GThreadXpWaiter **my_owner; -}; - -static GThreadXpWaiter * -g_thread_xp_waiter_get (void) -{ - GThreadXpWaiter *waiter; - - waiter = TlsGetValue (g_thread_xp_waiter_tls); - - if G_UNLIKELY (waiter == NULL) - { - waiter = malloc (sizeof (GThreadXpWaiter)); - if (waiter == NULL) - g_thread_abort (GetLastError (), "malloc"); - waiter->event = CreateEvent (0, FALSE, FALSE, NULL); - if (waiter->event == NULL) - g_thread_abort (GetLastError (), "CreateEvent"); - waiter->my_owner = NULL; - - TlsSetValue (g_thread_xp_waiter_tls, waiter); - } - - return waiter; -} - -static void __stdcall -g_thread_xp_CallThisOnThreadExit (void) -{ - GThreadXpWaiter *waiter; - - waiter = TlsGetValue (g_thread_xp_waiter_tls); - - if (waiter != NULL) - { - TlsSetValue (g_thread_xp_waiter_tls, NULL); - CloseHandle (waiter->event); - free (waiter); - } -} - -/* {{{2 SRWLock emulation */ -typedef struct -{ - CRITICAL_SECTION writer_lock; - gboolean ever_shared; /* protected by writer_lock */ - gboolean writer_locked; /* protected by writer_lock */ - - /* below is only ever touched if ever_shared becomes true */ - CRITICAL_SECTION atomicity; - GThreadXpWaiter *queued_writer; /* protected by atomicity lock */ - gint num_readers; /* protected by atomicity lock */ -} GThreadSRWLock; - -static void __stdcall -g_thread_xp_InitializeSRWLock (gpointer mutex) -{ - *(GThreadSRWLock * volatile *) mutex = NULL; -} - -static void __stdcall -g_thread_xp_DeleteSRWLock (gpointer mutex) -{ - GThreadSRWLock *lock = *(GThreadSRWLock * volatile *) mutex; - - if (lock) - { - if (lock->ever_shared) - DeleteCriticalSection (&lock->atomicity); - - DeleteCriticalSection (&lock->writer_lock); - free (lock); - } -} - -static GThreadSRWLock * __stdcall -g_thread_xp_get_srwlock (GThreadSRWLock * volatile *lock) -{ - GThreadSRWLock *result; - - /* It looks like we're missing some barriers here, but this code only - * ever runs on Windows XP, which in turn only ever runs on hardware - * with a relatively rigid memory model. The 'volatile' will take - * care of the compiler. - */ - result = *lock; - - if G_UNLIKELY (result == NULL) - { - EnterCriticalSection (&g_thread_xp_lock); - - /* Check again */ - result = *lock; - if (result == NULL) - { - result = malloc (sizeof (GThreadSRWLock)); - - if (result == NULL) - g_thread_abort (errno, "malloc"); - - InitializeCriticalSection (&result->writer_lock); - result->writer_locked = FALSE; - result->ever_shared = FALSE; - *lock = result; - } - - LeaveCriticalSection (&g_thread_xp_lock); - } - - return result; -} - -static void __stdcall -g_thread_xp_AcquireSRWLockExclusive (gpointer mutex) -{ - GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); - - EnterCriticalSection (&lock->writer_lock); - - /* CRITICAL_SECTION is reentrant, but SRWLock is not. - * Detect the deadlock that would occur on later Windows version. - */ - g_assert (!lock->writer_locked); - lock->writer_locked = TRUE; - - if (lock->ever_shared) - { - GThreadXpWaiter *waiter = NULL; - - EnterCriticalSection (&lock->atomicity); - if (lock->num_readers > 0) - lock->queued_writer = waiter = g_thread_xp_waiter_get (); - LeaveCriticalSection (&lock->atomicity); - - if (waiter != NULL) - WaitForSingleObject (waiter->event, INFINITE); - - lock->queued_writer = NULL; - } -} - -static BOOLEAN __stdcall -g_thread_xp_TryAcquireSRWLockExclusive (gpointer mutex) -{ - GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); - - if (!TryEnterCriticalSection (&lock->writer_lock)) - return FALSE; - - /* CRITICAL_SECTION is reentrant, but SRWLock is not. - * Ensure that this properly returns FALSE (as SRWLock would). - */ - if G_UNLIKELY (lock->writer_locked) - { - LeaveCriticalSection (&lock->writer_lock); - return FALSE; - } - - lock->writer_locked = TRUE; - - if (lock->ever_shared) - { - gboolean available; - - EnterCriticalSection (&lock->atomicity); - available = lock->num_readers == 0; - LeaveCriticalSection (&lock->atomicity); - - if (!available) - { - LeaveCriticalSection (&lock->writer_lock); - return FALSE; - } - } - - return TRUE; -} - -static void __stdcall -g_thread_xp_ReleaseSRWLockExclusive (gpointer mutex) -{ - GThreadSRWLock *lock = *(GThreadSRWLock * volatile *) mutex; - - lock->writer_locked = FALSE; - - /* We need this until we fix some weird parts of GLib that try to - * unlock freshly-allocated mutexes. - */ - if (lock != NULL) - LeaveCriticalSection (&lock->writer_lock); -} - -static void -g_thread_xp_srwlock_become_reader (GThreadSRWLock *lock) -{ - if G_UNLIKELY (!lock->ever_shared) - { - InitializeCriticalSection (&lock->atomicity); - lock->queued_writer = NULL; - lock->num_readers = 0; - - lock->ever_shared = TRUE; - } - - EnterCriticalSection (&lock->atomicity); - lock->num_readers++; - LeaveCriticalSection (&lock->atomicity); -} - -static void __stdcall -g_thread_xp_AcquireSRWLockShared (gpointer mutex) -{ - GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); - - EnterCriticalSection (&lock->writer_lock); - - /* See g_thread_xp_AcquireSRWLockExclusive */ - g_assert (!lock->writer_locked); - - g_thread_xp_srwlock_become_reader (lock); - - LeaveCriticalSection (&lock->writer_lock); -} - -static BOOLEAN __stdcall -g_thread_xp_TryAcquireSRWLockShared (gpointer mutex) -{ - GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); - - if (!TryEnterCriticalSection (&lock->writer_lock)) - return FALSE; - - /* See g_thread_xp_AcquireSRWLockExclusive */ - if G_UNLIKELY (lock->writer_locked) - { - LeaveCriticalSection (&lock->writer_lock); - return FALSE; - } - - g_thread_xp_srwlock_become_reader (lock); - - LeaveCriticalSection (&lock->writer_lock); - - return TRUE; -} - -static void __stdcall -g_thread_xp_ReleaseSRWLockShared (gpointer mutex) -{ - GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); - - EnterCriticalSection (&lock->atomicity); - - lock->num_readers--; - - if (lock->num_readers == 0 && lock->queued_writer) - SetEvent (lock->queued_writer->event); - - LeaveCriticalSection (&lock->atomicity); -} - -/* {{{2 CONDITION_VARIABLE emulation */ -typedef struct -{ - volatile GThreadXpWaiter *first; - volatile GThreadXpWaiter **last_ptr; -} GThreadXpCONDITION_VARIABLE; - -static void __stdcall -g_thread_xp_InitializeConditionVariable (gpointer cond) -{ - *(GThreadXpCONDITION_VARIABLE * volatile *) cond = NULL; -} - -static void __stdcall -g_thread_xp_DeleteConditionVariable (gpointer cond) -{ - GThreadXpCONDITION_VARIABLE *cv = *(GThreadXpCONDITION_VARIABLE * volatile *) cond; - - if (cv) - free (cv); -} - -static GThreadXpCONDITION_VARIABLE * __stdcall -g_thread_xp_get_condition_variable (GThreadXpCONDITION_VARIABLE * volatile *cond) -{ - GThreadXpCONDITION_VARIABLE *result; - - /* It looks like we're missing some barriers here, but this code only - * ever runs on Windows XP, which in turn only ever runs on hardware - * with a relatively rigid memory model. The 'volatile' will take - * care of the compiler. - */ - result = *cond; - - if G_UNLIKELY (result == NULL) - { - result = malloc (sizeof (GThreadXpCONDITION_VARIABLE)); - - if (result == NULL) - g_thread_abort (errno, "malloc"); - - result->first = NULL; - result->last_ptr = &result->first; - - if (InterlockedCompareExchangePointer (cond, result, NULL) != NULL) - { - free (result); - result = *cond; - } - } - - return result; -} - -static BOOL __stdcall -g_thread_xp_SleepConditionVariableSRW (gpointer cond, - gpointer mutex, - DWORD timeout, - ULONG flags) -{ - GThreadXpCONDITION_VARIABLE *cv = g_thread_xp_get_condition_variable (cond); - GThreadXpWaiter *waiter = g_thread_xp_waiter_get (); - DWORD status; - - waiter->next = NULL; - - EnterCriticalSection (&g_thread_xp_lock); - waiter->my_owner = cv->last_ptr; - *cv->last_ptr = waiter; - cv->last_ptr = &waiter->next; - LeaveCriticalSection (&g_thread_xp_lock); - - g_mutex_unlock (mutex); - status = WaitForSingleObject (waiter->event, timeout); - - if (status != WAIT_TIMEOUT && status != WAIT_OBJECT_0) - g_thread_abort (GetLastError (), "WaitForSingleObject"); - g_mutex_lock (mutex); - - if (status == WAIT_TIMEOUT) - { - EnterCriticalSection (&g_thread_xp_lock); - if (waiter->my_owner) - { - if (waiter->next) - waiter->next->my_owner = waiter->my_owner; - else - cv->last_ptr = waiter->my_owner; - *waiter->my_owner = waiter->next; - waiter->my_owner = NULL; - } - LeaveCriticalSection (&g_thread_xp_lock); - } - - return status == WAIT_OBJECT_0; -} - -static void __stdcall -g_thread_xp_WakeConditionVariable (gpointer cond) -{ - GThreadXpCONDITION_VARIABLE *cv = g_thread_xp_get_condition_variable (cond); - volatile GThreadXpWaiter *waiter; - - EnterCriticalSection (&g_thread_xp_lock); - - waiter = cv->first; - if (waiter != NULL) - { - waiter->my_owner = NULL; - cv->first = waiter->next; - if (cv->first != NULL) - cv->first->my_owner = &cv->first; - else - cv->last_ptr = &cv->first; - } - - if (waiter != NULL) - SetEvent (waiter->event); - - LeaveCriticalSection (&g_thread_xp_lock); -} - -static void __stdcall -g_thread_xp_WakeAllConditionVariable (gpointer cond) -{ - GThreadXpCONDITION_VARIABLE *cv = g_thread_xp_get_condition_variable (cond); - volatile GThreadXpWaiter *waiter; - - EnterCriticalSection (&g_thread_xp_lock); - - waiter = cv->first; - cv->first = NULL; - cv->last_ptr = &cv->first; - - while (waiter != NULL) - { - volatile GThreadXpWaiter *next; - - next = waiter->next; - SetEvent (waiter->event); - waiter->my_owner = NULL; - waiter = next; - } - - LeaveCriticalSection (&g_thread_xp_lock); -} - -/* {{{2 XP Setup */ -static void -g_thread_xp_init (void) -{ - static const GThreadImplVtable g_thread_xp_impl_vtable = { - g_thread_xp_CallThisOnThreadExit, - g_thread_xp_InitializeSRWLock, - g_thread_xp_DeleteSRWLock, - g_thread_xp_AcquireSRWLockExclusive, - g_thread_xp_TryAcquireSRWLockExclusive, - g_thread_xp_ReleaseSRWLockExclusive, - g_thread_xp_AcquireSRWLockShared, - g_thread_xp_TryAcquireSRWLockShared, - g_thread_xp_ReleaseSRWLockShared, - g_thread_xp_InitializeConditionVariable, - g_thread_xp_DeleteConditionVariable, - g_thread_xp_SleepConditionVariableSRW, - g_thread_xp_WakeAllConditionVariable, - g_thread_xp_WakeConditionVariable - }; - - InitializeCriticalSection (&g_thread_xp_lock); - g_thread_xp_waiter_tls = TlsAlloc (); - - g_thread_impl_vtable = g_thread_xp_impl_vtable; -} - /* {{{1 Epilogue */ -static gboolean -g_thread_lookup_native_funcs (void) -{ - GThreadImplVtable native_vtable = { 0, }; - HMODULE kernel32; - - kernel32 = GetModuleHandle ("KERNEL32.DLL"); - - if (kernel32 == NULL) - return FALSE; - -#define GET_FUNC(name) if ((native_vtable.name = (void *) GetProcAddress (kernel32, #name)) == NULL) return FALSE - GET_FUNC(InitializeSRWLock); - GET_FUNC(AcquireSRWLockExclusive); - GET_FUNC(TryAcquireSRWLockExclusive); - GET_FUNC(ReleaseSRWLockExclusive); - GET_FUNC(AcquireSRWLockShared); - GET_FUNC(TryAcquireSRWLockShared); - GET_FUNC(ReleaseSRWLockShared); - - GET_FUNC(InitializeConditionVariable); - GET_FUNC(SleepConditionVariableSRW); - GET_FUNC(WakeAllConditionVariable); - GET_FUNC(WakeConditionVariable); -#undef GET_FUNC - - g_thread_impl_vtable = native_vtable; - - return TRUE; -} - void g_thread_win32_init (void) { - if (!g_thread_lookup_native_funcs ()) - g_thread_xp_init (); - InitializeCriticalSection (&g_private_lock); #ifndef _MSC_VER @@ -1109,9 +580,6 @@ g_thread_win32_thread_detach (void) } } while (dtors_called); - - if (g_thread_impl_vtable.CallThisOnThreadExit) - g_thread_impl_vtable.CallThisOnThreadExit (); } void |