Prevent calling into g_cond_wait resp. g_mutex_lock/unlock directly to

2006-05-10  Sebastian Wilhelmi  <wilhelmi@google.com>

	* gthread/gthread-posix.c, gthread/gthread-win32.c: Prevent
	calling into g_cond_wait resp. g_mutex_lock/unlock directly to
	avoid recursions into the errorcheking mutex code (and out of
	principle anyway). (#335198, Chris Wilson)
This commit is contained in:
Sebastian Wilhelmi
2006-05-11 00:08:31 +00:00
committed by Sebastian Wilhelmi
parent a194e2e971
commit 685da6b099
4 changed files with 87 additions and 71 deletions

View File

@@ -1,5 +1,10 @@
2006-05-10 Sebastian Wilhelmi <wilhelmi@google.com> 2006-05-10 Sebastian Wilhelmi <wilhelmi@google.com>
* gthread/gthread-posix.c, gthread/gthread-win32.c: Prevent
calling into g_cond_wait resp. g_mutex_lock/unlock directly to
avoid recursions into the errorcheking mutex code (and out of
principle anyway). (#335198, Chris Wilson)
* tests/errorcheck-mutex-test.c: Adapt to GLib coding standards. * tests/errorcheck-mutex-test.c: Adapt to GLib coding standards.
2006-05-09 Sebastian Wilhelmi <wilhelmi@google.com> 2006-05-09 Sebastian Wilhelmi <wilhelmi@google.com>

View File

@@ -1,5 +1,10 @@
2006-05-10 Sebastian Wilhelmi <wilhelmi@google.com> 2006-05-10 Sebastian Wilhelmi <wilhelmi@google.com>
* gthread/gthread-posix.c, gthread/gthread-win32.c: Prevent
calling into g_cond_wait resp. g_mutex_lock/unlock directly to
avoid recursions into the errorcheking mutex code (and out of
principle anyway). (#335198, Chris Wilson)
* tests/errorcheck-mutex-test.c: Adapt to GLib coding standards. * tests/errorcheck-mutex-test.c: Adapt to GLib coding standards.
2006-05-09 Sebastian Wilhelmi <wilhelmi@google.com> 2006-05-09 Sebastian Wilhelmi <wilhelmi@google.com>

View File

@@ -24,10 +24,10 @@
* Modified by the GLib Team and others 1997-2000. See the AUTHORS * Modified by the GLib Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog * file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with * files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/. * GLib at ftp://ftp.gtk.org/pub/gtk/.
*/ */
/* /*
* MT safe * MT safe
*/ */
@@ -90,7 +90,7 @@ static gboolean posix_check_cmd_prio_warned = FALSE;
# define pthread_key_create(a, b) pthread_keycreate (a, b) # define pthread_key_create(a, b) pthread_keycreate (a, b)
# define pthread_attr_init(a) pthread_attr_create (a) # define pthread_attr_init(a) pthread_attr_create (a)
# define pthread_attr_destroy(a) pthread_attr_delete (a) # define pthread_attr_destroy(a) pthread_attr_delete (a)
# define pthread_create(a, b, c, d) pthread_create (a, *b, c, d) # define pthread_create(a, b, c, d) pthread_create (a, *b, c, d)
# define mutexattr_default (pthread_mutexattr_default) # define mutexattr_default (pthread_mutexattr_default)
# define condattr_default (pthread_condattr_default) # define condattr_default (pthread_condattr_default)
#else /* neither G_THREADS_IMPL_POSIX nor G_THREADS_IMPL_DCE are defined */ #else /* neither G_THREADS_IMPL_POSIX nor G_THREADS_IMPL_DCE are defined */
@@ -121,7 +121,7 @@ static gulong g_thread_min_stack_size = 0;
#if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES) #if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES)
#define HAVE_G_THREAD_IMPL_INIT #define HAVE_G_THREAD_IMPL_INIT
static void static void
g_thread_impl_init(void) g_thread_impl_init(void)
{ {
#ifdef _SC_THREAD_STACK_MIN #ifdef _SC_THREAD_STACK_MIN
@@ -136,8 +136,8 @@ g_thread_impl_init(void)
priority_normal_value = sched.sched_priority; priority_normal_value = sched.sched_priority;
} }
# else /* G_THREADS_IMPL_DCE */ # else /* G_THREADS_IMPL_DCE */
posix_check_cmd (priority_normal_value = posix_check_cmd (priority_normal_value =
pthread_getprio (*(pthread_t*)thread, pthread_getprio (*(pthread_t*)thread,
g_thread_priority_map [priority])); g_thread_priority_map [priority]));
# endif # endif
#endif /* HAVE_PRIORITIES */ #endif /* HAVE_PRIORITIES */
@@ -149,7 +149,7 @@ static GMutex *
g_mutex_new_posix_impl (void) g_mutex_new_posix_impl (void)
{ {
GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1); GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
posix_check_cmd (pthread_mutex_init ((pthread_mutex_t *) result, posix_check_cmd (pthread_mutex_init ((pthread_mutex_t *) result,
mutexattr_default)); mutexattr_default));
return result; return result;
} }
@@ -191,7 +191,7 @@ static GCond *
g_cond_new_posix_impl (void) g_cond_new_posix_impl (void)
{ {
GCond *result = (GCond *) g_new (pthread_cond_t, 1); GCond *result = (GCond *) g_new (pthread_cond_t, 1);
posix_check_cmd (pthread_cond_init ((pthread_cond_t *) result, posix_check_cmd (pthread_cond_init ((pthread_cond_t *) result,
condattr_default)); condattr_default));
return result; return result;
} }
@@ -199,7 +199,7 @@ g_cond_new_posix_impl (void)
/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait /* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
can be taken directly, as signature and semantic are right, but can be taken directly, as signature and semantic are right, but
without error check then!!!!, we might want to change this without error check then!!!!, we might want to change this
therfore. */ therefore. */
#define G_NSEC_PER_SEC 1000000000 #define G_NSEC_PER_SEC 1000000000
@@ -217,27 +217,30 @@ g_cond_timed_wait_posix_impl (GCond * cond,
if (!abs_time) if (!abs_time)
{ {
g_cond_wait (cond, entered_mutex); result = pthread_cond_wait ((pthread_cond_t *)cond,
return TRUE; (pthread_mutex_t *) entered_mutex);
timed_out = FALSE;
} }
else
{
end_time.tv_sec = abs_time->tv_sec;
end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
end_time.tv_sec = abs_time->tv_sec; g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
result = pthread_cond_timedwait ((pthread_cond_t *) cond,
(pthread_mutex_t *) entered_mutex,
&end_time);
result = pthread_cond_timedwait ((pthread_cond_t *) cond,
(pthread_mutex_t *) entered_mutex,
&end_time);
#ifdef G_THREADS_IMPL_POSIX #ifdef G_THREADS_IMPL_POSIX
timed_out = (result == ETIMEDOUT); timed_out = (result == ETIMEDOUT);
#else /* G_THREADS_IMPL_DCE */ #else /* G_THREADS_IMPL_DCE */
timed_out = (result == -1) && (errno == EAGAIN); timed_out = (result == -1) && (errno == EAGAIN);
#endif #endif
}
if (!timed_out) if (!timed_out)
posix_check_err (posix_error (result), "pthread_cond_timedwait"); posix_check_err (posix_error (result), "pthread_cond_timedwait");
return !timed_out; return !timed_out;
} }
@@ -277,7 +280,7 @@ g_private_get_posix_impl (GPrivate * private_key)
#else /* G_THREADS_IMPL_DCE */ #else /* G_THREADS_IMPL_DCE */
{ {
void* data; void* data;
posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key, posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key,
&data)); &data));
return data; return data;
} }
@@ -285,8 +288,8 @@ g_private_get_posix_impl (GPrivate * private_key)
} }
static void static void
g_thread_create_posix_impl (GThreadFunc thread_func, g_thread_create_posix_impl (GThreadFunc thread_func,
gpointer arg, gpointer arg,
gulong stack_size, gulong stack_size,
gboolean joinable, gboolean joinable,
gboolean bound, gboolean bound,
@@ -302,7 +305,7 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT); g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
posix_check_cmd (pthread_attr_init (&attr)); posix_check_cmd (pthread_attr_init (&attr));
#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
if (stack_size) if (stack_size)
{ {
@@ -324,7 +327,7 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
posix_check_cmd (pthread_attr_setdetachstate (&attr, posix_check_cmd (pthread_attr_setdetachstate (&attr,
joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED)); joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
#endif /* G_THREADS_IMPL_POSIX */ #endif /* G_THREADS_IMPL_POSIX */
#ifdef HAVE_PRIORITIES #ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX # ifdef G_THREADS_IMPL_POSIX
{ {
@@ -334,11 +337,11 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched)); posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched));
} }
# else /* G_THREADS_IMPL_DCE */ # else /* G_THREADS_IMPL_DCE */
posix_check_cmd_prio posix_check_cmd_prio
(pthread_attr_setprio (&attr, g_thread_priority_map [priority])); (pthread_attr_setprio (&attr, g_thread_priority_map [priority]));
# endif /* G_THREADS_IMPL_DCE */ # endif /* G_THREADS_IMPL_DCE */
#endif /* HAVE_PRIORITIES */ #endif /* HAVE_PRIORITIES */
ret = posix_error (pthread_create (thread, &attr, ret = posix_error (pthread_create (thread, &attr,
(void* (*)(void*))thread_func, arg)); (void* (*)(void*))thread_func, arg));
posix_check_cmd (pthread_attr_destroy (&attr)); posix_check_cmd (pthread_attr_destroy (&attr));
@@ -358,7 +361,7 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
#endif /* G_THREADS_IMPL_DCE */ #endif /* G_THREADS_IMPL_DCE */
} }
static void static void
g_thread_yield_posix_impl (void) g_thread_yield_posix_impl (void)
{ {
POSIX_YIELD_FUNC; POSIX_YIELD_FUNC;
@@ -366,13 +369,13 @@ g_thread_yield_posix_impl (void)
static void static void
g_thread_join_posix_impl (gpointer thread) g_thread_join_posix_impl (gpointer thread)
{ {
gpointer ignore; gpointer ignore;
posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore)); posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
} }
static void static void
g_thread_exit_posix_impl (void) g_thread_exit_posix_impl (void)
{ {
pthread_exit (NULL); pthread_exit (NULL);
} }
@@ -387,14 +390,14 @@ g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
{ {
struct sched_param sched; struct sched_param sched;
int policy; int policy;
posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy, posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy,
&sched)); &sched));
sched.sched_priority = g_thread_priority_map [priority]; sched.sched_priority = g_thread_priority_map [priority];
posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy, posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy,
&sched)); &sched));
} }
# else /* G_THREADS_IMPL_DCE */ # else /* G_THREADS_IMPL_DCE */
posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread, posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread,
g_thread_priority_map [priority])); g_thread_priority_map [priority]));
# endif # endif
#endif /* HAVE_PRIORITIES */ #endif /* HAVE_PRIORITIES */

View File

@@ -25,10 +25,10 @@
* Modified by the GLib Team and others 1997-2000. See the AUTHORS * Modified by the GLib Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog * file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with * files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/. * GLib at ftp://ftp.gtk.org/pub/gtk/.
*/ */
/* /*
* MT safe * MT safe
*/ */
@@ -76,6 +76,9 @@ static GDestroyNotify g_private_destructors[G_PRIVATE_MAX];
static guint g_private_next = 0; static guint g_private_next = 0;
/* A "forward" declaration of this structure */
static GThreadFunctions g_thread_functions_for_glib_use_default;
typedef struct _GThreadData GThreadData; typedef struct _GThreadData GThreadData;
struct _GThreadData struct _GThreadData
{ {
@@ -85,7 +88,7 @@ struct _GThreadData
gboolean joinable; gboolean joinable;
}; };
struct _GCond struct _GCond
{ {
GPtrArray *array; GPtrArray *array;
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
@@ -165,7 +168,7 @@ static gboolean
g_mutex_trylock_win32_impl (GMutex * mutex) g_mutex_trylock_win32_impl (GMutex * mutex)
{ {
DWORD result; DWORD result;
win32_check_for_error (WAIT_FAILED != win32_check_for_error (WAIT_FAILED !=
(result = WaitForSingleObject (*(HANDLE *)mutex, 0))); (result = WaitForSingleObject (*(HANDLE *)mutex, 0)));
return result != WAIT_TIMEOUT; return result != WAIT_TIMEOUT;
} }
@@ -236,12 +239,12 @@ g_cond_wait_internal (GCond *cond,
g_ptr_array_add (cond->array, event); g_ptr_array_add (cond->array, event);
LeaveCriticalSection (&cond->lock); LeaveCriticalSection (&cond->lock);
g_mutex_unlock (entered_mutex); g_thread_functions_for_glib_use_default.mutex_unlock (entered_mutex);
win32_check_for_error (WAIT_FAILED != win32_check_for_error (WAIT_FAILED !=
(retval = WaitForSingleObject (event, milliseconds))); (retval = WaitForSingleObject (event, milliseconds)));
g_mutex_lock (entered_mutex); g_thread_functions_for_glib_use_default.mutex_lock (entered_mutex);
if (retval == WAIT_TIMEOUT) if (retval == WAIT_TIMEOUT)
{ {
@@ -252,7 +255,7 @@ g_cond_wait_internal (GCond *cond,
* wait for the signal, this time with no timeout, to reset * wait for the signal, this time with no timeout, to reset
* it. retval is set again to honour the late arrival of the * it. retval is set again to honour the late arrival of the
* signal */ * signal */
win32_check_for_error (WAIT_FAILED != win32_check_for_error (WAIT_FAILED !=
(retval = WaitForSingleObject (event, 0))); (retval = WaitForSingleObject (event, 0)));
LeaveCriticalSection (&cond->lock); LeaveCriticalSection (&cond->lock);
@@ -270,7 +273,7 @@ g_cond_wait_internal (GCond *cond,
return retval != WAIT_TIMEOUT; return retval != WAIT_TIMEOUT;
} }
static void static void
g_cond_wait_win32_impl (GCond *cond, g_cond_wait_win32_impl (GCond *cond,
GMutex *entered_mutex) GMutex *entered_mutex)
{ {
@@ -281,7 +284,7 @@ g_cond_wait_win32_impl (GCond *cond,
} }
static gboolean static gboolean
g_cond_timed_wait_win32_impl (GCond *cond, g_cond_timed_wait_win32_impl (GCond *cond,
GMutex *entered_mutex, GMutex *entered_mutex,
GTimeVal *abs_time) GTimeVal *abs_time)
{ {
@@ -302,9 +305,9 @@ g_cond_timed_wait_win32_impl (GCond *cond,
to_wait = 0; to_wait = 0;
else else
to_wait = (abs_time->tv_sec - current_time.tv_sec) * 1000 + to_wait = (abs_time->tv_sec - current_time.tv_sec) * 1000 +
(abs_time->tv_usec - current_time.tv_usec) / 1000; (abs_time->tv_usec - current_time.tv_usec) / 1000;
} }
return g_cond_wait_internal (cond, entered_mutex, to_wait); return g_cond_wait_internal (cond, entered_mutex, to_wait);
} }
@@ -381,13 +384,13 @@ g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority)
g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW); g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT); g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
win32_check_for_error (SetThreadPriority (target->thread, win32_check_for_error (SetThreadPriority (target->thread,
g_thread_priority_map [priority])); g_thread_priority_map [priority]));
} }
static void static void
g_thread_self_win32_impl (gpointer thread) g_thread_self_win32_impl (gpointer thread)
{ {
GThreadData *self = TlsGetValue (g_thread_self_tls); GThreadData *self = TlsGetValue (g_thread_self_tls);
if (!self) if (!self)
@@ -396,19 +399,19 @@ g_thread_self_win32_impl (gpointer thread)
HANDLE handle = GetCurrentThread (); HANDLE handle = GetCurrentThread ();
HANDLE process = GetCurrentProcess (); HANDLE process = GetCurrentProcess ();
self = g_new (GThreadData, 1); self = g_new (GThreadData, 1);
win32_check_for_error (DuplicateHandle (process, handle, process, win32_check_for_error (DuplicateHandle (process, handle, process,
&self->thread, 0, FALSE, &self->thread, 0, FALSE,
DUPLICATE_SAME_ACCESS)); DUPLICATE_SAME_ACCESS));
win32_check_for_error (TlsSetValue (g_thread_self_tls, self)); win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
self->func = NULL; self->func = NULL;
self->data = NULL; self->data = NULL;
self->joinable = FALSE; self->joinable = FALSE;
} }
*(GThreadData **)thread = self; *(GThreadData **)thread = self;
} }
static void static void
g_thread_exit_win32_impl (void) g_thread_exit_win32_impl (void)
{ {
GThreadData *self = TlsGetValue (g_thread_self_tls); GThreadData *self = TlsGetValue (g_thread_self_tls);
@@ -430,12 +433,12 @@ g_thread_exit_win32_impl (void)
{ {
GDestroyNotify destructor = g_private_destructors[i]; GDestroyNotify destructor = g_private_destructors[i];
GDestroyNotify data = array[i]; GDestroyNotify data = array[i];
if (data) if (data)
some_data_non_null = TRUE; some_data_non_null = TRUE;
array[i] = NULL; array[i] = NULL;
if (destructor && data) if (destructor && data)
destructor (data); destructor (data);
} }
@@ -445,7 +448,7 @@ g_thread_exit_win32_impl (void)
win32_check_for_error (TlsSetValue (g_private_tls, NULL)); win32_check_for_error (TlsSetValue (g_private_tls, NULL));
} }
if (self) if (self)
{ {
if (!self->joinable) if (!self->joinable)
@@ -471,7 +474,7 @@ g_thread_proxy (gpointer data)
GThreadData *self = (GThreadData*) data; GThreadData *self = (GThreadData*) data;
win32_check_for_error (TlsSetValue (g_thread_self_tls, self)); win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
self->func (self->data); self->func (self->data);
g_thread_exit_win32_impl (); g_thread_exit_win32_impl ();
@@ -482,35 +485,35 @@ g_thread_proxy (gpointer data)
} }
static void static void
g_thread_create_win32_impl (GThreadFunc func, g_thread_create_win32_impl (GThreadFunc func,
gpointer data, gpointer data,
gulong stack_size, gulong stack_size,
gboolean joinable, gboolean joinable,
gboolean bound, gboolean bound,
GThreadPriority priority, GThreadPriority priority,
gpointer thread, gpointer thread,
GError **error) GError **error)
{ {
guint ignore; guint ignore;
GThreadData *retval; GThreadData *retval;
g_return_if_fail (func); g_return_if_fail (func);
g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW); g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT); g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
retval = g_new(GThreadData, 1); retval = g_new(GThreadData, 1);
retval->func = func; retval->func = func;
retval->data = data; retval->data = data;
retval->joinable = joinable; retval->joinable = joinable;
retval->thread = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_proxy, retval->thread = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_proxy,
retval, 0, &ignore); retval, 0, &ignore);
if (retval->thread == NULL) if (retval->thread == NULL)
{ {
gchar *win_error = g_win32_error_message (GetLastError ()); gchar *win_error = g_win32_error_message (GetLastError ());
g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
"Error creating thread: %s", win_error); "Error creating thread: %s", win_error);
g_free (retval); g_free (retval);
g_free (win_error); g_free (win_error);
@@ -522,7 +525,7 @@ g_thread_create_win32_impl (GThreadFunc func,
g_thread_set_priority_win32_impl (thread, priority); g_thread_set_priority_win32_impl (thread, priority);
} }
static void static void
g_thread_yield_win32_impl (void) g_thread_yield_win32_impl (void)
{ {
Sleep(0); Sleep(0);
@@ -535,7 +538,7 @@ g_thread_join_win32_impl (gpointer thread)
g_return_if_fail (target->joinable); g_return_if_fail (target->joinable);
win32_check_for_error (WAIT_FAILED != win32_check_for_error (WAIT_FAILED !=
WaitForSingleObject (target->thread, INFINITE)); WaitForSingleObject (target->thread, INFINITE));
win32_check_for_error (CloseHandle (target->thread)); win32_check_for_error (CloseHandle (target->thread));
@@ -578,12 +581,12 @@ g_thread_impl_init ()
return; return;
beenhere = TRUE; beenhere = TRUE;
win32_check_for_error (TLS_OUT_OF_INDEXES != win32_check_for_error (TLS_OUT_OF_INDEXES !=
(g_thread_self_tls = TlsAlloc ())); (g_thread_self_tls = TlsAlloc ()));
win32_check_for_error (TLS_OUT_OF_INDEXES != win32_check_for_error (TLS_OUT_OF_INDEXES !=
(g_private_tls = TlsAlloc ())); (g_private_tls = TlsAlloc ()));
win32_check_for_error (TLS_OUT_OF_INDEXES != win32_check_for_error (TLS_OUT_OF_INDEXES !=
(g_cond_event_tls = TlsAlloc ())); (g_cond_event_tls = TlsAlloc ()));
InitializeCriticalSection (&g_thread_global_spinlock); InitializeCriticalSection (&g_thread_global_spinlock);
@@ -597,10 +600,10 @@ g_thread_impl_init ()
{ {
try_enter_critical_section = (GTryEnterCriticalSectionFunc) try_enter_critical_section = (GTryEnterCriticalSectionFunc)
GetProcAddress(kernel32, "TryEnterCriticalSection"); GetProcAddress(kernel32, "TryEnterCriticalSection");
/* Even if TryEnterCriticalSection is found, it is not /* Even if TryEnterCriticalSection is found, it is not
* necessarily working..., we have to check it */ * necessarily working..., we have to check it */
if (try_enter_critical_section && if (try_enter_critical_section &&
try_enter_critical_section (&g_thread_global_spinlock)) try_enter_critical_section (&g_thread_global_spinlock))
{ {
LeaveCriticalSection (&g_thread_global_spinlock); LeaveCriticalSection (&g_thread_global_spinlock);