mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-15 04:05:11 +01:00
Revamped errorcheck mutexes and added errorcheck cond_wait() and
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. * 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.
This commit is contained in:
parent
dd58473e07
commit
fe0f325777
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2000-11-27 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* gthread.h: Add void in empty function arg list
|
* gthread.h: Add void in empty function arg list
|
||||||
|
@ -391,11 +391,12 @@ g_thread_create_proxy (gpointer data)
|
|||||||
|
|
||||||
g_assert (data);
|
g_assert (data);
|
||||||
|
|
||||||
/* the lock makes sure, that thread->system_thread is written,
|
/* This has to happen before G_LOCK, as that might call g_thread_self */
|
||||||
before thread->func is called. See g_thread_create */
|
|
||||||
|
|
||||||
G_LOCK (g_thread_create);
|
|
||||||
g_private_set (g_thread_specific_private, data);
|
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_UNLOCK (g_thread_create);
|
G_UNLOCK (g_thread_create);
|
||||||
|
|
||||||
thread->func (thread->arg);
|
thread->func (thread->arg);
|
||||||
|
@ -145,47 +145,52 @@ void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
|
|||||||
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
|
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
|
||||||
|
|
||||||
/* shorthands for conditional and unconditional function calls */
|
/* 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
|
(*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))
|
(g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
|
||||||
#define G_THREAD_ECF(op, fail, mutex, name, type) \
|
#define G_THREAD_ECF(op, fail, mutex, type) \
|
||||||
(g_thread_supported () ? \
|
(g_thread_supported () ? ((type(*)(GMutex*, gulong, gchar*)) \
|
||||||
((type(*)(GMutex*, gulong, gchar*, gchar*)) \
|
|
||||||
(*g_thread_functions_for_glib_use . op)) \
|
(*g_thread_functions_for_glib_use . op)) \
|
||||||
(mutex, G_MUTEX_DEBUG_MAGIC, G_STRINGIFY (name), G_STRLOC) : (fail))
|
(mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
|
||||||
|
|
||||||
#ifndef G_ERRORCHECK_MUTEXES
|
#ifndef G_ERRORCHECK_MUTEXES
|
||||||
#define g_mutex_lock_with_debug_name(mutex, name) \
|
# define g_mutex_lock(mutex) \
|
||||||
G_THREAD_CF (mutex_lock, (void)0, (mutex))
|
G_THREAD_CF (mutex_lock, (void)0, (mutex))
|
||||||
#define g_mutex_trylock_with_debug_name(mutex, name) \
|
# define g_mutex_trylock(mutex) \
|
||||||
G_THREAD_CF (mutex_trylock, TRUE, (mutex))
|
G_THREAD_CF (mutex_trylock, TRUE, (mutex))
|
||||||
#define g_mutex_unlock_with_debug_name(mutex, name) \
|
# define g_mutex_unlock(mutex) \
|
||||||
G_THREAD_CF (mutex_unlock, (void)0, (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 */
|
#else /* G_ERRORCHECK_MUTEXES */
|
||||||
#define g_mutex_lock_with_debug_name(mutex, name) \
|
# define g_mutex_lock(mutex) \
|
||||||
G_THREAD_ECF (mutex_lock, (void)0, mutex, name, void)
|
G_THREAD_ECF (mutex_lock, (void)0, mutex, void)
|
||||||
#define g_mutex_trylock_with_debug_name(mutex, name) \
|
# define g_mutex_trylock(mutex) \
|
||||||
G_THREAD_ECF (mutex_trylock, TRUE, mutex, name, gboolean)
|
G_THREAD_ECF (mutex_trylock, TRUE, mutex, gboolean)
|
||||||
#define g_mutex_unlock_with_debug_name(mutex, name) \
|
# define g_mutex_unlock(mutex) \
|
||||||
G_THREAD_ECF (mutex_unlock, (void)0, mutex, name, void)
|
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 */
|
#endif /* G_ERRORCHECK_MUTEXES */
|
||||||
|
|
||||||
#define g_thread_supported() (g_threads_got_initialized)
|
#define g_thread_supported() (g_threads_got_initialized)
|
||||||
#define g_mutex_new() G_THREAD_UF (mutex_new, ())
|
#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_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
|
||||||
#define g_cond_new() G_THREAD_UF (cond_new, ())
|
#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_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_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_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_new(destructor) G_THREAD_UF (private_new, (destructor))
|
||||||
#define g_private_get(private_key) G_THREAD_CF (private_get, \
|
#define g_private_get(private_key) G_THREAD_CF (private_get, \
|
||||||
((gpointer)private_key), \
|
((gpointer)private_key), \
|
||||||
@ -215,11 +220,11 @@ void g_thread_set_priority (GThread *thread,
|
|||||||
* use
|
* use
|
||||||
*/
|
*/
|
||||||
#define g_static_mutex_lock(mutex) \
|
#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) \
|
#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) \
|
#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
|
struct _GStaticPrivate
|
||||||
{
|
{
|
||||||
|
@ -391,11 +391,12 @@ g_thread_create_proxy (gpointer data)
|
|||||||
|
|
||||||
g_assert (data);
|
g_assert (data);
|
||||||
|
|
||||||
/* the lock makes sure, that thread->system_thread is written,
|
/* This has to happen before G_LOCK, as that might call g_thread_self */
|
||||||
before thread->func is called. See g_thread_create */
|
|
||||||
|
|
||||||
G_LOCK (g_thread_create);
|
|
||||||
g_private_set (g_thread_specific_private, data);
|
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_UNLOCK (g_thread_create);
|
G_UNLOCK (g_thread_create);
|
||||||
|
|
||||||
thread->func (thread->arg);
|
thread->func (thread->arg);
|
||||||
|
55
gthread.h
55
gthread.h
@ -145,47 +145,52 @@ void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
|
|||||||
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
|
GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex);
|
||||||
|
|
||||||
/* shorthands for conditional and unconditional function calls */
|
/* 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
|
(*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))
|
(g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
|
||||||
#define G_THREAD_ECF(op, fail, mutex, name, type) \
|
#define G_THREAD_ECF(op, fail, mutex, type) \
|
||||||
(g_thread_supported () ? \
|
(g_thread_supported () ? ((type(*)(GMutex*, gulong, gchar*)) \
|
||||||
((type(*)(GMutex*, gulong, gchar*, gchar*)) \
|
|
||||||
(*g_thread_functions_for_glib_use . op)) \
|
(*g_thread_functions_for_glib_use . op)) \
|
||||||
(mutex, G_MUTEX_DEBUG_MAGIC, G_STRINGIFY (name), G_STRLOC) : (fail))
|
(mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
|
||||||
|
|
||||||
#ifndef G_ERRORCHECK_MUTEXES
|
#ifndef G_ERRORCHECK_MUTEXES
|
||||||
#define g_mutex_lock_with_debug_name(mutex, name) \
|
# define g_mutex_lock(mutex) \
|
||||||
G_THREAD_CF (mutex_lock, (void)0, (mutex))
|
G_THREAD_CF (mutex_lock, (void)0, (mutex))
|
||||||
#define g_mutex_trylock_with_debug_name(mutex, name) \
|
# define g_mutex_trylock(mutex) \
|
||||||
G_THREAD_CF (mutex_trylock, TRUE, (mutex))
|
G_THREAD_CF (mutex_trylock, TRUE, (mutex))
|
||||||
#define g_mutex_unlock_with_debug_name(mutex, name) \
|
# define g_mutex_unlock(mutex) \
|
||||||
G_THREAD_CF (mutex_unlock, (void)0, (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 */
|
#else /* G_ERRORCHECK_MUTEXES */
|
||||||
#define g_mutex_lock_with_debug_name(mutex, name) \
|
# define g_mutex_lock(mutex) \
|
||||||
G_THREAD_ECF (mutex_lock, (void)0, mutex, name, void)
|
G_THREAD_ECF (mutex_lock, (void)0, mutex, void)
|
||||||
#define g_mutex_trylock_with_debug_name(mutex, name) \
|
# define g_mutex_trylock(mutex) \
|
||||||
G_THREAD_ECF (mutex_trylock, TRUE, mutex, name, gboolean)
|
G_THREAD_ECF (mutex_trylock, TRUE, mutex, gboolean)
|
||||||
#define g_mutex_unlock_with_debug_name(mutex, name) \
|
# define g_mutex_unlock(mutex) \
|
||||||
G_THREAD_ECF (mutex_unlock, (void)0, mutex, name, void)
|
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 */
|
#endif /* G_ERRORCHECK_MUTEXES */
|
||||||
|
|
||||||
#define g_thread_supported() (g_threads_got_initialized)
|
#define g_thread_supported() (g_threads_got_initialized)
|
||||||
#define g_mutex_new() G_THREAD_UF (mutex_new, ())
|
#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_mutex_free(mutex) G_THREAD_CF (mutex_free, (void)0, (mutex))
|
||||||
#define g_cond_new() G_THREAD_UF (cond_new, ())
|
#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_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_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_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_new(destructor) G_THREAD_UF (private_new, (destructor))
|
||||||
#define g_private_get(private_key) G_THREAD_CF (private_get, \
|
#define g_private_get(private_key) G_THREAD_CF (private_get, \
|
||||||
((gpointer)private_key), \
|
((gpointer)private_key), \
|
||||||
@ -215,11 +220,11 @@ void g_thread_set_priority (GThread *thread,
|
|||||||
* use
|
* use
|
||||||
*/
|
*/
|
||||||
#define g_static_mutex_lock(mutex) \
|
#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) \
|
#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) \
|
#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
|
struct _GStaticPrivate
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
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>
|
2000-11-21 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||||
|
|
||||||
* gthread-impl.c, gthread-posix.c, gthread-solaris.c: Removed
|
* gthread-impl.c, gthread-posix.c, gthread-solaris.c: Removed
|
||||||
|
@ -69,7 +69,6 @@ void g_messages_init (void);
|
|||||||
typedef struct _ErrorCheckInfo ErrorCheckInfo;
|
typedef struct _ErrorCheckInfo ErrorCheckInfo;
|
||||||
struct _ErrorCheckInfo
|
struct _ErrorCheckInfo
|
||||||
{
|
{
|
||||||
gchar *name;
|
|
||||||
gchar *location;
|
gchar *location;
|
||||||
GThread *owner;
|
GThread *owner;
|
||||||
};
|
};
|
||||||
@ -83,42 +82,26 @@ g_mutex_new_errorcheck_impl (void)
|
|||||||
return retval;
|
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
|
static void
|
||||||
g_mutex_lock_errorcheck_impl (GMutex *mutex,
|
g_mutex_lock_errorcheck_impl (GMutex *mutex,
|
||||||
gulong magic,
|
gulong magic,
|
||||||
gchar *name,
|
|
||||||
gchar *location)
|
gchar *location)
|
||||||
{
|
{
|
||||||
ErrorCheckInfo *info;
|
ErrorCheckInfo *info;
|
||||||
GThread *self = g_thread_self ();
|
GThread *self = g_thread_self ();
|
||||||
|
|
||||||
|
if (magic != G_MUTEX_DEBUG_MAGIC)
|
||||||
|
location = "unknown";
|
||||||
|
|
||||||
if (G_MUTEX_DEBUG_INFO (mutex) == NULL)
|
if (G_MUTEX_DEBUG_INFO (mutex) == NULL)
|
||||||
{
|
{
|
||||||
/* if the debug info is NULL, we have not yet locked that mutex,
|
/* if the debug info is NULL, we have not yet locked that mutex,
|
||||||
* so we do it now */
|
* so we do it now */
|
||||||
g_thread_functions_for_glib_use_default.mutex_lock (mutex);
|
g_thread_functions_for_glib_use_default.mutex_lock (mutex);
|
||||||
/* Now we have to check again, because anothe thread might mave
|
/* Now we have to check again, because another thread might have
|
||||||
* locked the mutex at the same time, we did. This technique is
|
* tried to lock the mutex at the same time we did. This
|
||||||
* not 100% save on systems without decent cache coherence,
|
* technique is not 100% save on systems without decent cache
|
||||||
* but we have no choice */
|
* coherence, but we have no choice */
|
||||||
if (G_MUTEX_DEBUG_INFO (mutex) == NULL)
|
if (G_MUTEX_DEBUG_INFO (mutex) == NULL)
|
||||||
{
|
{
|
||||||
info = G_MUTEX_DEBUG_INFO (mutex) = g_new0 (ErrorCheckInfo, 1);
|
info = G_MUTEX_DEBUG_INFO (mutex) = g_new0 (ErrorCheckInfo, 1);
|
||||||
@ -128,56 +111,70 @@ g_mutex_lock_errorcheck_impl (GMutex *mutex,
|
|||||||
|
|
||||||
info = G_MUTEX_DEBUG_INFO (mutex);
|
info = G_MUTEX_DEBUG_INFO (mutex);
|
||||||
if (info->owner == self)
|
if (info->owner == self)
|
||||||
g_error ("Trying to recursivly lock the mutex '%s' at '%s', "
|
g_error ("Trying to recursivly lock a mutex at '%s', "
|
||||||
"previously locked by name '%s' at '%s'",
|
"previously locked at '%s'",
|
||||||
name, location, info->name, info->location);
|
location, info->location);
|
||||||
|
|
||||||
g_thread_functions_for_glib_use_default.mutex_lock (mutex);
|
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
|
static gboolean
|
||||||
g_mutex_trylock_errorcheck_impl (GMutex *mutex,
|
g_mutex_trylock_errorcheck_impl (GMutex *mutex,
|
||||||
gulong magic,
|
gulong magic,
|
||||||
gchar *name,
|
|
||||||
gchar *location)
|
gchar *location)
|
||||||
{
|
{
|
||||||
ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
|
ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
|
||||||
GThread *self = g_thread_self ();
|
GThread *self = g_thread_self ();
|
||||||
|
|
||||||
|
if (magic != G_MUTEX_DEBUG_MAGIC)
|
||||||
|
location = "unknown";
|
||||||
|
|
||||||
if (!info)
|
if (!info)
|
||||||
{
|
{
|
||||||
/* This mutex has not yet been used, so simply lock and return TRUE */
|
/* 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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->owner == self)
|
if (info->owner == self)
|
||||||
g_error ("Trying to recursivly lock the mutex '%s' at '%s', "
|
g_error ("Trying to recursivly lock a mutex at '%s', "
|
||||||
"previously locked by name '%s' at '%s'",
|
"previously locked at '%s'",
|
||||||
name, location, info->name, info->location);
|
location, info->location);
|
||||||
|
|
||||||
if (!g_thread_functions_for_glib_use_default.mutex_trylock (mutex))
|
if (!g_thread_functions_for_glib_use_default.mutex_trylock (mutex))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
fill_info (info, self, magic, name, location);
|
info->owner = self;
|
||||||
|
info->location = location;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_mutex_unlock_errorcheck_impl (GMutex *mutex,
|
g_mutex_unlock_errorcheck_impl (GMutex *mutex,
|
||||||
gulong magic,
|
gulong magic,
|
||||||
gchar *name,
|
|
||||||
gchar *location)
|
gchar *location)
|
||||||
{
|
{
|
||||||
ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
|
ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex);
|
||||||
GThread *self = g_thread_self ();
|
GThread *self = g_thread_self ();
|
||||||
|
|
||||||
if (magic != G_MUTEX_DEBUG_MAGIC)
|
if (magic != G_MUTEX_DEBUG_MAGIC)
|
||||||
name = location = "unknown";
|
location = "unknown";
|
||||||
if (!info || info->owner != self)
|
|
||||||
g_error ("Trying to unlock the unlocked mutex '%s' at '%s'",
|
if (!info || info->owner == NULL)
|
||||||
name, location);
|
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->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_unlock (mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,6 +185,73 @@ g_mutex_free_errorcheck_impl (GMutex *mutex)
|
|||||||
g_thread_functions_for_glib_use_default.mutex_free (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 */
|
/* unshadow function declaration. See glib.h */
|
||||||
#undef g_thread_init
|
#undef g_thread_init
|
||||||
|
|
||||||
@ -207,6 +271,8 @@ g_thread_init_with_errorcheck_mutexes (GThreadFunctions* init)
|
|||||||
errorcheck_functions.mutex_unlock =
|
errorcheck_functions.mutex_unlock =
|
||||||
(void (*)(GMutex *)) g_mutex_unlock_errorcheck_impl;
|
(void (*)(GMutex *)) g_mutex_unlock_errorcheck_impl;
|
||||||
errorcheck_functions.mutex_free = g_mutex_free_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);
|
g_thread_init (&errorcheck_functions);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user