mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 00:12:19 +01:00 
			
		
		
		
	Renamed to glib/gthreadprivate.h and moved system thread identifier
2006-05-09 Sebastian Wilhelmi <wilhelmi@google.com> * glib/gthreadinit.h: Renamed to glib/gthreadprivate.h and moved system thread identifier comparision and assignment macros from glib/gthread.c to glib/gthreadprivate.h. * glib/Makefile.am, glib/gatomic.c, glib/gconvert.c, glib/gmain.c, glib/gmem.c, glib/gmessages.c, glib/grand.c, glib/gslice.c, glib/gthread.c, glib/gutils.c, gthread/gthread-impl.c: Use glib/gthreadprivate.h instead of glib/gthreadinit.h. * gthread/gthread-impl.c: Use GSystemThread instead of GThread for owner determination. This fixes #311043 and is mostly modeled after the patch from jylefort@FreeBSD.org.
This commit is contained in:
		
				
					committed by
					
						 Sebastian Wilhelmi
						Sebastian Wilhelmi
					
				
			
			
				
	
			
			
			
						parent
						
							307391459d
						
					
				
				
					commit
					e4f8f3b95c
				
			
							
								
								
									
										15
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -1,5 +1,20 @@ | ||||
| 2006-05-09  Sebastian Wilhelmi  <wilhelmi@google.com> | ||||
|  | ||||
| 	* glib/gthreadinit.h: Renamed to glib/gthreadprivate.h and moved | ||||
| 	system thread identifier comparision and assignment macros from | ||||
| 	glib/gthread.c to glib/gthreadprivate.h. | ||||
|  | ||||
| 	* glib/Makefile.am, glib/gatomic.c, glib/gconvert.c, glib/gmain.c, | ||||
| 	glib/gmem.c, glib/gmessages.c, glib/grand.c, glib/gslice.c, | ||||
| 	glib/gthread.c, glib/gutils.c, gthread/gthread-impl.c: Use | ||||
| 	glib/gthreadprivate.h instead of glib/gthreadinit.h. | ||||
|  | ||||
| 	* gthread/gthread-impl.c: Use GSystemThread instead of GThread for | ||||
| 	owner determination. (#311043, jylefort@FreeBSD.org) | ||||
|  | ||||
| 	* tests/Makefile.am, tests/errorcheck-mutex-test: New test program | ||||
| 	to test for all checked violations. | ||||
|  | ||||
| 	* glib/gprintf.c, glib/gspawn-win32.c, glib/gutf8.c, | ||||
| 	gthread/gthread-impl.c, gthread/gthread-posix.c, | ||||
| 	gthread/gthread-win32.c: Use canonical include form for internal | ||||
|   | ||||
| @@ -1,5 +1,20 @@ | ||||
| 2006-05-09  Sebastian Wilhelmi  <wilhelmi@google.com> | ||||
|  | ||||
| 	* glib/gthreadinit.h: Renamed to glib/gthreadprivate.h and moved | ||||
| 	system thread identifier comparision and assignment macros from | ||||
| 	glib/gthread.c to glib/gthreadprivate.h. | ||||
|  | ||||
| 	* glib/Makefile.am, glib/gatomic.c, glib/gconvert.c, glib/gmain.c, | ||||
| 	glib/gmem.c, glib/gmessages.c, glib/grand.c, glib/gslice.c, | ||||
| 	glib/gthread.c, glib/gutils.c, gthread/gthread-impl.c: Use | ||||
| 	glib/gthreadprivate.h instead of glib/gthreadinit.h. | ||||
|  | ||||
| 	* gthread/gthread-impl.c: Use GSystemThread instead of GThread for | ||||
| 	owner determination. (#311043, jylefort@FreeBSD.org) | ||||
|  | ||||
| 	* tests/Makefile.am, tests/errorcheck-mutex-test: New test program | ||||
| 	to test for all checked violations. | ||||
|  | ||||
| 	* glib/gprintf.c, glib/gspawn-win32.c, glib/gutf8.c, | ||||
| 	gthread/gthread-impl.c, gthread/gthread-posix.c, | ||||
| 	gthread/gthread-win32.c: Use canonical include form for internal | ||||
|   | ||||
| @@ -112,7 +112,7 @@ libglib_2_0_la_SOURCES = 	\ | ||||
| 	gstrfuncs.c		\ | ||||
| 	gstring.c		\ | ||||
| 	gthread.c       	\ | ||||
| 	gthreadinit.h		\ | ||||
| 	gthreadprivate.h	\ | ||||
| 	gthreadpool.c   	\ | ||||
| 	gtimer.c		\ | ||||
| 	gtree.c			\ | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
| #include "config.h" | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
|  | ||||
| #if defined (__GNUC__) | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gprintfint.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
|  | ||||
| #ifdef G_PLATFORM_WIN32 | ||||
| #define STRICT | ||||
|   | ||||
| @@ -37,7 +37,7 @@ | ||||
| /* #define G_MAIN_POLL_DEBUG */ | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include <signal.h> | ||||
| #include <sys/types.h> | ||||
| #include <time.h> | ||||
|   | ||||
| @@ -35,7 +35,7 @@ | ||||
| #include <signal.h> | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
|  | ||||
| #define MEM_PROFILE_TABLE_SIZE 4096 | ||||
|   | ||||
| @@ -44,7 +44,7 @@ | ||||
| #include "glib.h" | ||||
| #include "gdebug.h" | ||||
| #include "gprintfint.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
|  | ||||
| #ifdef G_OS_WIN32 | ||||
|   | ||||
| @@ -48,7 +48,7 @@ | ||||
| #endif | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
|  | ||||
| #ifdef G_OS_WIN32 | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include "gmem.h"               /* gslice.h */ | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
| #include "glib.h" | ||||
| #ifdef HAVE_UNISTD_H | ||||
|   | ||||
| @@ -41,26 +41,9 @@ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
|  | ||||
| #if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P | ||||
| # define g_system_thread_equal_simple(thread1, thread2)			\ | ||||
|    ((thread1).dummy_pointer == (thread2).dummy_pointer) | ||||
| # define g_system_thread_assign(dest, src)				\ | ||||
|    ((dest).dummy_pointer = (src).dummy_pointer) | ||||
| #else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */ | ||||
| # define g_system_thread_equal_simple(thread1, thread2)			\ | ||||
|    (memcmp (&(thread1), &(thread2), GLIB_SIZEOF_SYSTEM_THREAD) == 0) | ||||
| # define g_system_thread_assign(dest, src)				\ | ||||
|    (memcpy (&(dest), &(src), GLIB_SIZEOF_SYSTEM_THREAD)) | ||||
| #endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */ | ||||
|  | ||||
| #define g_system_thread_equal(thread1, thread2)				\ | ||||
|   (g_thread_functions_for_glib_use.thread_equal ? 			\ | ||||
|    g_thread_functions_for_glib_use.thread_equal (&(thread1), &(thread2)) :\ | ||||
|    g_system_thread_equal_simple((thread1), (thread2))) | ||||
|  | ||||
| GQuark  | ||||
| g_thread_error_quark (void) | ||||
| { | ||||
|   | ||||
| @@ -1,4 +1,6 @@ | ||||
| /* gthreadinit.h - GLib internal thread initialization functions
 | ||||
| /* GLIB - Library of useful routines for C programming
 | ||||
|  * | ||||
|  * gthreadprivate.h - GLib internal thread system related declarations. | ||||
|  * | ||||
|  *  Copyright (C) 2003 Sebastian Wilhelmi | ||||
|  * | ||||
| @@ -18,11 +20,29 @@ | ||||
|  *   Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __G_THREADINIT_H__ | ||||
| #define __G_THREADINIT_H__ | ||||
| #ifndef __G_THREADPRIVATE_H__ | ||||
| #define __G_THREADPRIVATE_H__ | ||||
| 
 | ||||
| G_BEGIN_DECLS | ||||
| 
 | ||||
| /* System thread identifier comparision and assignment */ | ||||
| #if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P | ||||
| # define g_system_thread_equal_simple(thread1, thread2)			\ | ||||
|    ((thread1).dummy_pointer == (thread2).dummy_pointer) | ||||
| # define g_system_thread_assign(dest, src)				\ | ||||
|    ((dest).dummy_pointer = (src).dummy_pointer) | ||||
| #else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */ | ||||
| # define g_system_thread_equal_simple(thread1, thread2)			\ | ||||
|    (memcmp (&(thread1), &(thread2), GLIB_SIZEOF_SYSTEM_THREAD) == 0) | ||||
| # define g_system_thread_assign(dest, src)				\ | ||||
|    (memcpy (&(dest), &(src), GLIB_SIZEOF_SYSTEM_THREAD)) | ||||
| #endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */ | ||||
| 
 | ||||
| #define g_system_thread_equal(thread1, thread2)				\ | ||||
|   (g_thread_functions_for_glib_use.thread_equal ? 			\ | ||||
|    g_thread_functions_for_glib_use.thread_equal (&(thread1), &(thread2)) :\ | ||||
|    g_system_thread_equal_simple((thread1), (thread2))) | ||||
| 
 | ||||
| /* Is called from gthread/gthread-impl.c */ | ||||
| void g_thread_init_glib (void); | ||||
| 
 | ||||
| @@ -32,16 +52,17 @@ void _g_mem_thread_init_noprivate_nomessage (void) G_GNUC_INTERNAL; | ||||
| void _g_slice_thread_init_nomessage	    (void) G_GNUC_INTERNAL; | ||||
| void _g_messages_thread_init_nomessage      (void) G_GNUC_INTERNAL; | ||||
| 
 | ||||
| /* full fledged initializersa */ | ||||
| /* full fledged initializers */ | ||||
| void _g_convert_thread_init (void) G_GNUC_INTERNAL; | ||||
| void _g_rand_thread_init (void) G_GNUC_INTERNAL; | ||||
| void _g_main_thread_init (void) G_GNUC_INTERNAL; | ||||
| void _g_atomic_thread_init (void) G_GNUC_INTERNAL; | ||||
| void _g_utils_thread_init (void) G_GNUC_INTERNAL; | ||||
| 
 | ||||
| #ifdef G_OS_WIN32 | ||||
| void _g_win32_thread_init (void) G_GNUC_INTERNAL; | ||||
| #endif | ||||
| #endif /* G_OS_WIN32 */ | ||||
| 
 | ||||
| G_END_DECLS | ||||
|   | ||||
| #endif /* __G_THREADINIT_H__ */ | ||||
| 
 | ||||
| #endif /* __G_THREADPRIVATE_H__ */ | ||||
| @@ -56,7 +56,7 @@ | ||||
| #define	__G_UTILS_C__ | ||||
| #include "glib.h" | ||||
| #include "gprintfint.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
| #include "galias.h" | ||||
|  | ||||
| #ifdef	MAXPATHLEN | ||||
|   | ||||
| @@ -34,10 +34,11 @@ | ||||
| #include "config.h" | ||||
|  | ||||
| #include "glib.h" | ||||
| #include "gthreadinit.h" | ||||
| #include "gthreadprivate.h" | ||||
|  | ||||
| #ifdef G_THREADS_ENABLED | ||||
|  | ||||
| static GSystemThread zero_thread; /* This is initialized to all zero */ | ||||
| static gboolean thread_system_already_initialized = FALSE; | ||||
| static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT + 1]; | ||||
|  | ||||
| @@ -74,7 +75,7 @@ typedef struct _ErrorCheckInfo ErrorCheckInfo; | ||||
| struct _ErrorCheckInfo | ||||
| { | ||||
|   gchar *location; | ||||
|   GThread *owner; | ||||
|   GSystemThread owner; | ||||
| }; | ||||
|  | ||||
| static GMutex * | ||||
| @@ -92,7 +93,9 @@ g_mutex_lock_errorcheck_impl (GMutex *mutex, | ||||
| 			      gchar *location) | ||||
| { | ||||
|   ErrorCheckInfo *info; | ||||
|   GThread *self = g_thread_self (); | ||||
|   GSystemThread self; | ||||
|  | ||||
|   g_thread_functions_for_glib_use.thread_self (&self); | ||||
|  | ||||
|   if (magic != G_MUTEX_DEBUG_MAGIC) | ||||
|     location = "unknown"; | ||||
| @@ -114,14 +117,14 @@ g_mutex_lock_errorcheck_impl (GMutex *mutex, | ||||
|     } | ||||
|    | ||||
|   info = G_MUTEX_DEBUG_INFO (mutex); | ||||
|   if (info->owner == self) | ||||
|   if (g_system_thread_equal (info->owner, self)) | ||||
|     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); | ||||
|  | ||||
|   info->owner = self; | ||||
|   g_system_thread_assign (info->owner, self); | ||||
|   info->location = location; | ||||
| } | ||||
|  | ||||
| @@ -131,7 +134,9 @@ g_mutex_trylock_errorcheck_impl (GMutex *mutex, | ||||
| 				 gchar *location) | ||||
| { | ||||
|   ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex); | ||||
|   GThread *self = g_thread_self (); | ||||
|   GSystemThread self; | ||||
|  | ||||
|   g_thread_functions_for_glib_use.thread_self (&self); | ||||
|  | ||||
|   if (magic != G_MUTEX_DEBUG_MAGIC) | ||||
|     location = "unknown"; | ||||
| @@ -143,7 +148,7 @@ g_mutex_trylock_errorcheck_impl (GMutex *mutex, | ||||
|       return TRUE; | ||||
|     } | ||||
|  | ||||
|   if (info->owner == self) | ||||
|   if (g_system_thread_equal (info->owner, self)) | ||||
|     g_error ("Trying to recursivly lock a mutex at '%s', " | ||||
| 	     "previously locked at '%s'",  | ||||
| 	     location, info->location); | ||||
| @@ -151,7 +156,7 @@ g_mutex_trylock_errorcheck_impl (GMutex *mutex, | ||||
|   if (!g_thread_functions_for_glib_use_default.mutex_trylock (mutex)) | ||||
|     return FALSE; | ||||
|  | ||||
|   info->owner = self; | ||||
|   g_system_thread_assign (info->owner, self); | ||||
|   info->location = location; | ||||
|  | ||||
|   return TRUE; | ||||
| @@ -163,20 +168,22 @@ g_mutex_unlock_errorcheck_impl (GMutex *mutex, | ||||
| 				gchar *location) | ||||
| { | ||||
|   ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex); | ||||
|   GThread *self = g_thread_self (); | ||||
|   GSystemThread self; | ||||
|  | ||||
|   g_thread_functions_for_glib_use.thread_self (&self); | ||||
|  | ||||
|   if (magic != G_MUTEX_DEBUG_MAGIC) | ||||
|     location = "unknown"; | ||||
|  | ||||
|   if (!info || info->owner == NULL) | ||||
|   if (!info || g_system_thread_equal (info->owner, zero_thread)) | ||||
|     g_error ("Trying to unlock an unlocked mutex at '%s'", location); | ||||
|  | ||||
|   if (info->owner != self) | ||||
|   if (!g_system_thread_equal (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; | ||||
|   g_system_thread_assign (info->owner, zero_thread); | ||||
|   info->location = NULL; | ||||
|  | ||||
|   g_thread_functions_for_glib_use_default.mutex_unlock (mutex); | ||||
| @@ -192,7 +199,7 @@ g_mutex_free_errorcheck_impl (GMutex *mutex, | ||||
|   if (magic != G_MUTEX_DEBUG_MAGIC) | ||||
|     location = "unknown"; | ||||
|  | ||||
|   if (info && info->owner != NULL) | ||||
|   if (info && !g_system_thread_equal (info->owner, zero_thread)) | ||||
|     g_error ("Trying to free a locked mutex at '%s', " | ||||
| 	     "which was previously locked at '%s'",  | ||||
| 	     location, info->location); | ||||
| @@ -209,25 +216,27 @@ g_cond_wait_errorcheck_impl (GCond *cond, | ||||
| { | ||||
|    | ||||
|   ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex); | ||||
|   GThread *self = g_thread_self (); | ||||
|   GSystemThread self; | ||||
|  | ||||
|   g_thread_functions_for_glib_use.thread_self (&self); | ||||
|  | ||||
|   if (magic != G_MUTEX_DEBUG_MAGIC) | ||||
|     location = "unknown"; | ||||
|  | ||||
|   if (!info || info->owner == NULL) | ||||
|   if (!info || g_system_thread_equal (info->owner, zero_thread)) | ||||
|     g_error ("Trying to use an unlocked mutex in g_cond_wait() at '%s'", | ||||
| 	     location); | ||||
|  | ||||
|   if (info->owner != self) | ||||
|   if (!g_system_thread_equal (info->owner, self)) | ||||
|     g_error ("Trying to use a mutex locked by another thread in " | ||||
| 	     "g_cond_wait() at '%s'", location); | ||||
|  | ||||
|   info->owner = NULL; | ||||
|   g_system_thread_assign (info->owner, zero_thread); | ||||
|   location = info->location; | ||||
|  | ||||
|   g_thread_functions_for_glib_use_default.cond_wait (cond, mutex); | ||||
|  | ||||
|   info->owner = self; | ||||
|   g_system_thread_assign (info->owner, self); | ||||
|   info->location = location; | ||||
| } | ||||
|      | ||||
| @@ -240,28 +249,30 @@ g_cond_timed_wait_errorcheck_impl (GCond *cond, | ||||
| 				   gchar *location) | ||||
| { | ||||
|   ErrorCheckInfo *info = G_MUTEX_DEBUG_INFO (mutex); | ||||
|   GThread *self = g_thread_self (); | ||||
|   GSystemThread self; | ||||
|   gboolean retval; | ||||
|  | ||||
|   g_thread_functions_for_glib_use.thread_self (&self); | ||||
|  | ||||
|   if (magic != G_MUTEX_DEBUG_MAGIC) | ||||
|     location = "unknown"; | ||||
|  | ||||
|   if (!info || info->owner == NULL) | ||||
|   if (!info || g_system_thread_equal (info->owner, zero_thread)) | ||||
|     g_error ("Trying to use an unlocked mutex in g_cond_timed_wait() at '%s'", | ||||
| 	     location); | ||||
|  | ||||
|   if (info->owner != self) | ||||
|   if (!g_system_thread_equal (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; | ||||
|   g_system_thread_assign (info->owner, zero_thread); | ||||
|   location = info->location; | ||||
|    | ||||
|   retval = g_thread_functions_for_glib_use_default.cond_timed_wait (cond,  | ||||
| 								    mutex,  | ||||
| 								    end_time); | ||||
|  | ||||
|   info->owner = self; | ||||
|   g_system_thread_assign (info->owner, self); | ||||
|   info->location = location; | ||||
|  | ||||
|   return retval; | ||||
|   | ||||
| @@ -25,6 +25,7 @@ cxx-test | ||||
| date-test | ||||
| dirname-test | ||||
| env-test | ||||
| errorcheck-mutex-test | ||||
| file-test | ||||
| file-test-get-contents | ||||
| hash-test | ||||
|   | ||||
| @@ -49,12 +49,13 @@ endif | ||||
| if ENABLE_TIMELOOP | ||||
| timeloop = timeloop timeloop-closure | ||||
| endif | ||||
| noinst_PROGRAMS = testglib testgdate testgdateparser unicode-normalize unicode-collate $(timeloop) | ||||
| noinst_PROGRAMS = testglib testgdate testgdateparser unicode-normalize unicode-collate $(timeloop) errorcheck-mutex-test | ||||
| testglib_LDADD = $(libglib) | ||||
| patterntest_LDADD = $(libglib) | ||||
| testgdate_LDADD = $(libglib) | ||||
| testgdateparser_LDADD = $(libglib) | ||||
| unicode_normalize_LDADD = $(libglib) | ||||
| errorcheck_mutex_test_LDADD = $(libglib) $(libgthread) | ||||
| if ENABLE_TIMELOOP | ||||
| timeloop_LDADD = $(libglib) | ||||
| timeloop_closure_LDADD = $(libglib) $(libgobject) | ||||
|   | ||||
							
								
								
									
										131
									
								
								tests/errorcheck-mutex-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								tests/errorcheck-mutex-test.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| #undef G_DISABLE_ASSERT | ||||
| #undef G_LOG_DOMAIN | ||||
| #define G_ERRORCHECK_MUTEXES | ||||
|  | ||||
| #include <glib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
| static gpointer | ||||
| locking_thread (gpointer mutex) | ||||
| { | ||||
|   g_mutex_lock ((GMutex*)mutex); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
| lock_locked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   g_mutex_lock (mutex); | ||||
|   g_mutex_lock (mutex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| trylock_locked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   g_mutex_lock (mutex); | ||||
|   g_mutex_trylock (mutex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| unlock_unlocked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   g_mutex_lock (mutex); | ||||
|   g_mutex_unlock (mutex); | ||||
|   g_mutex_unlock (mutex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| free_locked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   g_mutex_lock (mutex); | ||||
|   g_mutex_free (mutex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wait_on_unlocked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   GCond* cond = g_cond_new (); | ||||
|   g_cond_wait (cond, mutex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| wait_on_otherwise_locked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   GCond* cond = g_cond_new (); | ||||
|   GThread* thread = g_thread_create (locking_thread, mutex, TRUE, NULL); | ||||
|   g_assert (thread != NULL); | ||||
|   g_usleep (G_USEC_PER_SEC); | ||||
|   g_cond_wait (cond, mutex); | ||||
| } | ||||
|  | ||||
| static void | ||||
| timed_wait_on_unlocked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   GCond* cond = g_cond_new (); | ||||
|   g_cond_timed_wait (cond, mutex, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| timed_wait_on_otherwise_locked_mutex () | ||||
| { | ||||
|   GMutex* mutex = g_mutex_new (); | ||||
|   GCond* cond = g_cond_new (); | ||||
|   GThread* thread = g_thread_create (locking_thread, mutex, TRUE, NULL); | ||||
|   g_assert (thread != NULL); | ||||
|   g_usleep (G_USEC_PER_SEC); | ||||
|   g_cond_timed_wait (cond, mutex, NULL); | ||||
| } | ||||
|  | ||||
| struct | ||||
| { | ||||
|   char *name; | ||||
|   void (*func)(); | ||||
| } func_table[] = | ||||
| { | ||||
|   {"lock_locked_mutex", lock_locked_mutex}, | ||||
|   {"trylock_locked_mutex", trylock_locked_mutex}, | ||||
|   {"unlock_unlocked_mutex", unlock_unlocked_mutex}, | ||||
|   {"free_locked_mutex", free_locked_mutex}, | ||||
|   {"wait_on_unlocked_mutex", wait_on_unlocked_mutex}, | ||||
|   {"wait_on_otherwise_locked_mutex", wait_on_otherwise_locked_mutex}, | ||||
|   {"timed_wait_on_unlocked_mutex", timed_wait_on_unlocked_mutex}, | ||||
|   {"timed_wait_on_otherwise_locked_mutex", | ||||
|    timed_wait_on_otherwise_locked_mutex} | ||||
| }; | ||||
|  | ||||
| int | ||||
| main (int argc, char* argv[]) | ||||
| { | ||||
|   int i; | ||||
|  | ||||
|   if (argc == 2) | ||||
|   { | ||||
|     for (i = 0; i < G_N_ELEMENTS (func_table); i++) | ||||
|     { | ||||
|       if (strcmp (func_table[i].name, argv[1]) == 0) | ||||
|       { | ||||
|         g_thread_init (NULL); | ||||
|         func_table[i].func (); | ||||
|         g_assert_not_reached (); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   fprintf (stderr, "Usage: errorcheck-mutex-test [TEST]\n\n"); | ||||
|   fprintf (stderr, "   where TEST can be one of:\n\n"); | ||||
|   for (i = 0; i < G_N_ELEMENTS (func_table); i++) | ||||
|   { | ||||
|     fprintf (stderr, "      %s\n", func_table[i].name); | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user