+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread.c: Set the thread data before locking the mutex, because
+ the locking call might use g_thread_self ().
+
+ * gthread.h: Do only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex. Add the
+ errorcheck capability for g_cond_wait and g_cond_timed_wait as
+ well.
+
2000-11-27 Havoc Pennington <hp@redhat.com>
* gthread.h: Add void in empty function arg list
g_assert (data);
- /* the lock makes sure, that thread->system_thread is written,
- before thread->func is called. See g_thread_create */
+ /* This has to happen before G_LOCK, as that might call g_thread_self */
+ g_private_set (g_thread_specific_private, data);
+ /* the lock makes sure, that thread->system_thread is written,
+ before thread->func is called. See g_thread_create. */
G_LOCK (g_thread_create);
- g_private_set (g_thread_specific_private, data);
G_UNLOCK (g_thread_create);
thread->func (thread->arg);
* mutexes will check for re-locking and re-unlocking */
/* Initialize thread system with errorcheck mutexes. vtable must be
- * NULL.Do not call directly. Use #define G_ERRORCHECK_MUTEXES
+ * NULL. Do not call directly. Use #define G_ERRORCHECK_MUTEXES
* instead.
*/
void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
/* shorthands for conditional and unconditional function calls */
-#define G_THREAD_UF(op, arglist) \
+
+#define G_THREAD_UF(op, arglist) \
(*g_thread_functions_for_glib_use . op) arglist
-#define G_THREAD_CF(op, fail, arg) \
+#define G_THREAD_CF(op, fail, arg) \
(g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
-#define G_THREAD_ECF(op, fail, mutex, name, type) \
- (g_thread_supported () ? \
- ((type(*)(GMutex*, gulong, gchar*, gchar*)) \
- (*g_thread_functions_for_glib_use . op)) \
- (mutex, G_MUTEX_DEBUG_MAGIC, G_STRINGIFY (name), G_STRLOC) : (fail))
+#define G_THREAD_ECF(op, fail, mutex, type) \
+ (g_thread_supported () ? ((type(*)(GMutex*, gulong, gchar*)) \
+ (*g_thread_functions_for_glib_use . op)) \
+ (mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
+
#ifndef G_ERRORCHECK_MUTEXES
-#define g_mutex_lock_with_debug_name(mutex, name) \
- G_THREAD_CF (mutex_lock, (void)0, (mutex))
-#define g_mutex_trylock_with_debug_name(mutex, name) \
- G_THREAD_CF (mutex_trylock, TRUE, (mutex))
-#define g_mutex_unlock_with_debug_name(mutex, name) \
- G_THREAD_CF (mutex_unlock, (void)0, (mutex))
+# define g_mutex_lock(mutex) \
+ G_THREAD_CF (mutex_lock, (void)0, (mutex))
+# define g_mutex_trylock(mutex) \
+ G_THREAD_CF (mutex_trylock, TRUE, (mutex))
+# define g_mutex_unlock(mutex) \
+ G_THREAD_CF (mutex_unlock, (void)0, (mutex))
+# define g_cond_wait(cond, mutex) \
+ G_THREAD_CF (cond_wait, (void)0, (cond, mutex))
+# define g_cond_timed_wait(cond, mutex, abs_time) \
+ G_THREAD_CF (cond_timed_wait, TRUE, (cond, mutex, abs_time))
#else /* G_ERRORCHECK_MUTEXES */
-#define g_mutex_lock_with_debug_name(mutex, name) \
- G_THREAD_ECF (mutex_lock, (void)0, mutex, name, void)
-#define g_mutex_trylock_with_debug_name(mutex, name) \
- G_THREAD_ECF (mutex_trylock, TRUE, mutex, name, gboolean)
-#define g_mutex_unlock_with_debug_name(mutex, name) \
- G_THREAD_ECF (mutex_unlock, (void)0, mutex, name, void)
+# define g_mutex_lock(mutex) \
+ G_THREAD_ECF (mutex_lock, (void)0, mutex, void)
+# define g_mutex_trylock(mutex) \
+ G_THREAD_ECF (mutex_trylock, TRUE, mutex, gboolean)
+# define g_mutex_unlock(mutex) \
+ G_THREAD_ECF (mutex_unlock, (void)0, mutex, void)
+# define g_cond_wait(cond, mutex) \
+ (g_thread_supported () ? ((void(*)(GCond*, GMutex*, gulong, gchar*))\
+ g_thread_functions_for_glib_use.cond_wait) \
+ (cond, mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (void) 0)
+# define g_cond_timed_wait(cond, mutex, abs_time) \
+ (g_thread_supported () ? \
+ ((gboolean(*)(GCond*, GMutex*, GTimeVal*, gulong, gchar*)) \
+ g_thread_functions_for_glib_use.cond_timed_wait) \
+ (cond, mutex, abs_time, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : TRUE)
#endif /* G_ERRORCHECK_MUTEXES */
#define g_thread_supported() (g_threads_got_initialized)
#define g_mutex_new() G_THREAD_UF (mutex_new, ())
-#define g_mutex_lock(mutex) g_mutex_lock_with_debug_name(mutex, mutex)
-#define g_mutex_trylock(mutex) g_mutex_trylock_with_debug_name(mutex, mutex)
-#define g_mutex_unlock(mutex) g_mutex_unlock_with_debug_name(mutex, mutex)
#define g_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
#define g_cond_new() G_THREAD_UF (cond_new, ())
#define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
#define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
-#define g_cond_wait(cond, mutex) G_THREAD_CF (cond_wait, (void)0, (cond, \
- mutex))
#define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
-#define g_cond_timed_wait(cond, mutex, abs_time) G_THREAD_CF (cond_timed_wait, \
- TRUE, \
- (cond, mutex, \
- abs_time))
-#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
-#define g_private_get(private_key) G_THREAD_CF (private_get, \
- ((gpointer)private_key), \
- (private_key))
+#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
+#define g_private_get(private_key) G_THREAD_CF (private_get, \
+ ((gpointer)private_key), \
+ (private_key))
#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
(void) (private_key = \
(GPrivate*) (value)), \
* use
*/
#define g_static_mutex_lock(mutex) \
- g_mutex_lock_with_debug_name (g_static_mutex_get_mutex (mutex), mutex)
+ g_mutex_lock (g_static_mutex_get_mutex (mutex))
#define g_static_mutex_trylock(mutex) \
- g_mutex_trylock_with_debug_name (g_static_mutex_get_mutex (mutex), mutex)
+ g_mutex_trylock (g_static_mutex_get_mutex (mutex))
#define g_static_mutex_unlock(mutex) \
- g_mutex_unlock_with_debug_name (g_static_mutex_get_mutex (mutex), mutex)
+ g_mutex_unlock (g_static_mutex_get_mutex (mutex))
struct _GStaticPrivate
{
g_assert (data);
- /* the lock makes sure, that thread->system_thread is written,
- before thread->func is called. See g_thread_create */
+ /* This has to happen before G_LOCK, as that might call g_thread_self */
+ g_private_set (g_thread_specific_private, data);
+ /* the lock makes sure, that thread->system_thread is written,
+ before thread->func is called. See g_thread_create. */
G_LOCK (g_thread_create);
- g_private_set (g_thread_specific_private, data);
G_UNLOCK (g_thread_create);
thread->func (thread->arg);
* mutexes will check for re-locking and re-unlocking */
/* Initialize thread system with errorcheck mutexes. vtable must be
- * NULL.Do not call directly. Use #define G_ERRORCHECK_MUTEXES
+ * NULL. Do not call directly. Use #define G_ERRORCHECK_MUTEXES
* instead.
*/
void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
/* shorthands for conditional and unconditional function calls */
-#define G_THREAD_UF(op, arglist) \
+
+#define G_THREAD_UF(op, arglist) \
(*g_thread_functions_for_glib_use . op) arglist
-#define G_THREAD_CF(op, fail, arg) \
+#define G_THREAD_CF(op, fail, arg) \
(g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
-#define G_THREAD_ECF(op, fail, mutex, name, type) \
- (g_thread_supported () ? \
- ((type(*)(GMutex*, gulong, gchar*, gchar*)) \
- (*g_thread_functions_for_glib_use . op)) \
- (mutex, G_MUTEX_DEBUG_MAGIC, G_STRINGIFY (name), G_STRLOC) : (fail))
+#define G_THREAD_ECF(op, fail, mutex, type) \
+ (g_thread_supported () ? ((type(*)(GMutex*, gulong, gchar*)) \
+ (*g_thread_functions_for_glib_use . op)) \
+ (mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
+
#ifndef G_ERRORCHECK_MUTEXES
-#define g_mutex_lock_with_debug_name(mutex, name) \
- G_THREAD_CF (mutex_lock, (void)0, (mutex))
-#define g_mutex_trylock_with_debug_name(mutex, name) \
- G_THREAD_CF (mutex_trylock, TRUE, (mutex))
-#define g_mutex_unlock_with_debug_name(mutex, name) \
- G_THREAD_CF (mutex_unlock, (void)0, (mutex))
+# define g_mutex_lock(mutex) \
+ G_THREAD_CF (mutex_lock, (void)0, (mutex))
+# define g_mutex_trylock(mutex) \
+ G_THREAD_CF (mutex_trylock, TRUE, (mutex))
+# define g_mutex_unlock(mutex) \
+ G_THREAD_CF (mutex_unlock, (void)0, (mutex))
+# define g_cond_wait(cond, mutex) \
+ G_THREAD_CF (cond_wait, (void)0, (cond, mutex))
+# define g_cond_timed_wait(cond, mutex, abs_time) \
+ G_THREAD_CF (cond_timed_wait, TRUE, (cond, mutex, abs_time))
#else /* G_ERRORCHECK_MUTEXES */
-#define g_mutex_lock_with_debug_name(mutex, name) \
- G_THREAD_ECF (mutex_lock, (void)0, mutex, name, void)
-#define g_mutex_trylock_with_debug_name(mutex, name) \
- G_THREAD_ECF (mutex_trylock, TRUE, mutex, name, gboolean)
-#define g_mutex_unlock_with_debug_name(mutex, name) \
- G_THREAD_ECF (mutex_unlock, (void)0, mutex, name, void)
+# define g_mutex_lock(mutex) \
+ G_THREAD_ECF (mutex_lock, (void)0, mutex, void)
+# define g_mutex_trylock(mutex) \
+ G_THREAD_ECF (mutex_trylock, TRUE, mutex, gboolean)
+# define g_mutex_unlock(mutex) \
+ G_THREAD_ECF (mutex_unlock, (void)0, mutex, void)
+# define g_cond_wait(cond, mutex) \
+ (g_thread_supported () ? ((void(*)(GCond*, GMutex*, gulong, gchar*))\
+ g_thread_functions_for_glib_use.cond_wait) \
+ (cond, mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (void) 0)
+# define g_cond_timed_wait(cond, mutex, abs_time) \
+ (g_thread_supported () ? \
+ ((gboolean(*)(GCond*, GMutex*, GTimeVal*, gulong, gchar*)) \
+ g_thread_functions_for_glib_use.cond_timed_wait) \
+ (cond, mutex, abs_time, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : TRUE)
#endif /* G_ERRORCHECK_MUTEXES */
#define g_thread_supported() (g_threads_got_initialized)
#define g_mutex_new() G_THREAD_UF (mutex_new, ())
-#define g_mutex_lock(mutex) g_mutex_lock_with_debug_name(mutex, mutex)
-#define g_mutex_trylock(mutex) g_mutex_trylock_with_debug_name(mutex, mutex)
-#define g_mutex_unlock(mutex) g_mutex_unlock_with_debug_name(mutex, mutex)
#define g_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
#define g_cond_new() G_THREAD_UF (cond_new, ())
#define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond))
#define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond))
-#define g_cond_wait(cond, mutex) G_THREAD_CF (cond_wait, (void)0, (cond, \
- mutex))
#define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond))
-#define g_cond_timed_wait(cond, mutex, abs_time) G_THREAD_CF (cond_timed_wait, \
- TRUE, \
- (cond, mutex, \
- abs_time))
-#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
-#define g_private_get(private_key) G_THREAD_CF (private_get, \
- ((gpointer)private_key), \
- (private_key))
+#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
+#define g_private_get(private_key) G_THREAD_CF (private_get, \
+ ((gpointer)private_key), \
+ (private_key))
#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
(void) (private_key = \
(GPrivate*) (value)), \
* use
*/
#define g_static_mutex_lock(mutex) \
- g_mutex_lock_with_debug_name (g_static_mutex_get_mutex (mutex), mutex)
+ g_mutex_lock (g_static_mutex_get_mutex (mutex))
#define g_static_mutex_trylock(mutex) \
- g_mutex_trylock_with_debug_name (g_static_mutex_get_mutex (mutex), mutex)
+ g_mutex_trylock (g_static_mutex_get_mutex (mutex))
#define g_static_mutex_unlock(mutex) \
- g_mutex_unlock_with_debug_name (g_static_mutex_get_mutex (mutex), mutex)
+ g_mutex_unlock (g_static_mutex_get_mutex (mutex))
struct _GStaticPrivate
{
+2000-11-28 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
+
+ * gthread-impl.c: Revamped errorcheck mutexes and added errorcheck
+ cond_wait() and cond_timed_wait() funtions. This makes he whole
+ thing work. Now we only show the location of the locking/unlocking
+ for -DG_ERRORCHECK_MUTEXES and not the name of the mutex.
+
2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* gthread-impl.c, gthread-posix.c, gthread-solaris.c: Removed
typedef struct _ErrorCheckInfo ErrorCheckInfo;
struct _ErrorCheckInfo
{
- gchar *name;
gchar *location;
GThread *owner;
};
return retval;
}
-static inline void
-fill_info (ErrorCheckInfo *info,
- GThread *self,
- gulong magic,
- gchar *name,
- gchar *location)
-{
- info->owner = self;
- if (magic == G_MUTEX_DEBUG_MAGIC)
- {
- /* We are used with special instrumented calls, where name and
- * location is provided as well, so use them */
- info->name = name;
- info->location = location;
- }
- else
- info->name = info->location = "unknown";
-}
-
static void
g_mutex_lock_errorcheck_impl (GMutex *mutex,
- gulong magic,
- gchar *name,
+ gulong magic,
gchar *location)
{
ErrorCheckInfo *info;
GThread *self = g_thread_self ();
+
+ if (magic != G_MUTEX_DEBUG_MAGIC)
+ location = "unknown";
+
if (G_MUTEX_DEBUG_INFO (mutex) == NULL)
{
/* if the debug info is NULL, we have not yet locked that mutex,
* so we do it now */
g_thread_functions_for_glib_use_default.mutex_lock (mutex);
- /* Now we have to check again, because anothe thread might mave
- * locked the mutex at the same time, we did. This technique is
- * not 100% save on systems without decent cache coherence,
- * but we have no choice */
+ /* Now we have to check again, because another thread might have
+ * tried to lock the mutex at the same time we did. This
+ * technique is not 100% save on systems without decent cache
+ * coherence, but we have no choice */
if (G_MUTEX_DEBUG_INFO (mutex) == NULL)
{
info = G_MUTEX_DEBUG_INFO (mutex) = g_new0 (ErrorCheckInfo, 1);
info = G_MUTEX_DEBUG_INFO (mutex);
if (info->owner == self)
- g_error ("Trying to recursivly lock the mutex '%s' at '%s', "
- "previously locked by name '%s' at '%s'",
- name, location, info->name, info->location);
+ g_error ("Trying to recursivly lock a mutex at '%s', "
+ "previously locked at '%s'",
+ location, info->location);
g_thread_functions_for_glib_use_default.mutex_lock (mutex);
- fill_info (info, self, magic, name, location);
+ info->owner = self;
+ info->location = location;
}
static gboolean
g_mutex_trylock_errorcheck_impl (GMutex *mutex,
gulong magic,
- gchar *name,
gchar *location)
{
ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
GThread *self = g_thread_self ();
+
+ if (magic != G_MUTEX_DEBUG_MAGIC)
+ location = "unknown";
+
if (!info)
{
/* This mutex has not yet been used, so simply lock and return TRUE */
- g_mutex_lock_errorcheck_impl (mutex, magic, name, location);
+ g_mutex_lock_errorcheck_impl (mutex, magic, location);
return TRUE;
}
+
if (info->owner == self)
- g_error ("Trying to recursivly lock the mutex '%s' at '%s', "
- "previously locked by name '%s' at '%s'",
- name, location, info->name, info->location);
+ g_error ("Trying to recursivly lock a mutex at '%s', "
+ "previously locked at '%s'",
+ location, info->location);
if (!g_thread_functions_for_glib_use_default.mutex_trylock (mutex))
return FALSE;
- fill_info (info, self, magic, name, location);
+ info->owner = self;
+ info->location = location;
+
return TRUE;
}
static void
g_mutex_unlock_errorcheck_impl (GMutex *mutex,
gulong magic,
- gchar *name,
gchar *location)
{
ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
GThread *self = g_thread_self ();
+
if (magic != G_MUTEX_DEBUG_MAGIC)
- name = location = "unknown";
- if (!info || info->owner != self)
- g_error ("Trying to unlock the unlocked mutex '%s' at '%s'",
- name, location);
+ location = "unknown";
+
+ if (!info || info->owner == NULL)
+ g_error ("Trying to unlock an unlocked mutex at '%s'", location);
+
+ if (info->owner != self)
+ g_warning ("Trying to unlock a mutex at '%s', "
+ "previously locked by a different thread at '%s'",
+ location, info->location);
+
info->owner = NULL;
- info->name = info->location = NULL;
+ info->location = NULL;
+
g_thread_functions_for_glib_use_default.mutex_unlock (mutex);
}
g_thread_functions_for_glib_use_default.mutex_free (mutex);
}
+static void
+g_cond_wait_errorcheck_impl (GCond *cond,
+ GMutex *mutex,
+ gulong magic,
+ gchar *location)
+{
+
+ ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+ GThread *self = g_thread_self ();
+
+ if (magic != G_MUTEX_DEBUG_MAGIC)
+ location = "unknown";
+
+ if (!info || info->owner == NULL)
+ g_error ("Trying to use an unlocked mutex in g_cond_wait() at '%s'",
+ location);
+
+ if (info->owner != self)
+ g_error ("Trying to use a mutex locked by another thread in "
+ "g_cond_wait() at '%s'", location);
+
+ info->owner = NULL;
+ location = info->location;
+
+ g_thread_functions_for_glib_use_default.cond_wait (cond, mutex);
+
+ info->owner = self;
+ info->location = location;
+}
+
+
+static gboolean
+g_cond_timed_wait_errorcheck_impl (GCond *cond,
+ GMutex *mutex,
+ GTimeVal *end_time,
+ gulong magic,
+ gchar *location)
+{
+ ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+ GThread *self = g_thread_self ();
+ gboolean retval;
+
+ if (magic != G_MUTEX_DEBUG_MAGIC)
+ location = "unknown";
+
+ if (!info || info->owner == NULL)
+ g_error ("Trying to use an unlocked mutex in g_cond_timed_wait() at '%s'",
+ location);
+
+ if (info->owner != self)
+ g_error ("Trying to use a mutex locked by another thread in "
+ "g_cond_timed_wait() at '%s'", location);
+
+ info->owner = NULL;
+ location = info->location;
+
+ retval = g_thread_functions_for_glib_use_default.cond_timed_wait (cond,
+ mutex,
+ end_time);
+
+ info->owner = self;
+ info->location = location;
+
+ return retval;
+}
+
+
/* unshadow function declaration. See glib.h */
#undef g_thread_init
errorcheck_functions.mutex_unlock =
(void (*)(GMutex *)) g_mutex_unlock_errorcheck_impl;
errorcheck_functions.mutex_free = g_mutex_free_errorcheck_impl;
+ errorcheck_functions.cond_wait = g_cond_wait_errorcheck_impl;
+ errorcheck_functions.cond_timed_wait = g_cond_timed_wait_errorcheck_impl;
g_thread_init (&errorcheck_functions);
}