* Copyright 1998-2001 Sebastian Wilhelmi; University of Karlsruhe
* Copyright 2001 Hans Breuer
*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
static DWORD
g_private_get_impl (GPrivate *key)
{
- DWORD impl = (DWORD) key->p;
+ DWORD impl = (DWORD) GPOINTER_TO_UINT(key->p);
if G_UNLIKELY (impl == 0)
{
EnterCriticalSection (&g_private_lock);
- impl = (DWORD) key->p;
+ impl = (UINT_PTR) key->p;
if (impl == 0)
{
GPrivateDestructor *destructor;
impl = TlsAlloc ();
- if (impl == TLS_OUT_OF_INDEXES)
+ if G_UNLIKELY (impl == 0)
+ {
+ /* Ignore TLS index 0 temporarily (as 0 is the indicator that we
+ * haven't allocated TLS yet) and alloc again;
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2058 */
+ DWORD impl2 = TlsAlloc ();
+ TlsFree (impl);
+ impl = impl2;
+ }
+
+ if (impl == TLS_OUT_OF_INDEXES || impl == 0)
g_thread_abort (0, "TlsAlloc");
if (key->notify != NULL)
void
g_system_thread_exit (void)
{
+ /* In static compilation, DllMain doesn't exist and so DLL_THREAD_DETACH
+ * case is never called and thread destroy notifications are not triggered.
+ * To ensure that notifications are correctly triggered in static
+ * compilation mode, we call directly the "detach" function here right
+ * before terminating the thread.
+ * As all win32 threads initialized through the glib API are run through
+ * the same proxy function g_thread_win32_proxy() which calls systematically
+ * g_system_thread_exit() when finishing, we obtain the same behavior as
+ * with dynamic compilation.
+ *
+ * WARNING: unfortunately this mechanism cannot work with threads created
+ * directly from the Windows API using CreateThread() or _beginthread/ex().
+ * It only works with threads created by using the glib API with
+ * g_system_thread_new(). If users need absolutely to use a thread NOT
+ * created with glib API under Windows and in static compilation mode, they
+ * should not use glib functions within their thread or they may encounter
+ * memory leaks when the thread finishes.
+ */
+#ifdef GLIB_STATIC_COMPILATION
+ g_thread_win32_thread_detach ();
+#endif
+
_endthreadex (0);
}
goto error;
}
- if (ResumeThread (thread->handle) == -1)
+ if (ResumeThread (thread->handle) == (DWORD) -1)
{
message = "Error resuming new thread";
goto error;
if ((!IsDebuggerPresent ()) && (SetThreadName_VEH_handle == NULL))
return;
- RaiseException (EXCEPTION_SET_THREAD_NAME, 0, infosize, (DWORD *) &info);
+ RaiseException (EXCEPTION_SET_THREAD_NAME, 0, infosize, (const ULONG_PTR *) &info);
#endif
}
typedef HRESULT (WINAPI *pSetThreadDescription) (HANDLE hThread,
PCWSTR lpThreadDescription);
static pSetThreadDescription SetThreadDescriptionFunc = NULL;
-HMODULE kernel32_module = NULL;
+static HMODULE kernel32_module = NULL;
static gboolean
g_thread_win32_load_library (void)
{
/* FIXME: Add support for UWP app */
#if !defined(G_WINAPI_ONLY_APP)
- static volatile gsize _init_once = 0;
+ static gsize _init_once = 0;
if (g_once_init_enter (&_init_once))
{
kernel32_module = LoadLibraryW (L"kernel32.dll");