diff --git a/ChangeLog b/ChangeLog index 044ecaeb5..dcba20216 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 044ecaeb5..dcba20216 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,31 @@ +1998-12-09 Sebastian Wilhelmi + + * Made the thread related code follow GNU coding standard. + + * Made a comment (HOLDS:) above each function, that expects the + given locks to be held. + + * Changed try_lock to trylock throughout. + + * glib.c: Eventually removed the #if 0'ed code for old GStaticMutex. + + * glib.c: Corrected g_trylock macro for G_DEBUG_LOCKS. + + * gmain.c (g_main_poll_add_unlocked): first take a new poll record + form the poll_free_list. + + * gmem.c, gstrfuncs.c, gutils.c: Made it MT safe. + + * gthraed/*.c: Added copyright headers. + + * gthread/gthread-solaris.c: do not use g_log for errors, as g_log + uses these module and endless recursions might happen, just use a + plain fprintf(stderr,...). + + * gthread/gthread.c (g_thread_try_init): Call g_mutex_init(). + + * gthread/testgthread.c: updated test program. + Tue Dec 8 18:49:56 1998 Owen Taylor * Start at adding thread-safety. (mostly work diff --git a/garray.c b/garray.c index 2bfc91da9..7f0803e3e 100644 --- a/garray.c +++ b/garray.c @@ -55,14 +55,14 @@ g_array_new (gboolean zero_terminated, { GRealArray *array; - g_lock(array_mem_chunk); + g_lock (array_mem_chunk); if (!array_mem_chunk) array_mem_chunk = g_mem_chunk_new ("array mem chunk", sizeof (GRealArray), 1024, G_ALLOC_AND_FREE); array = g_chunk_new (GRealArray, array_mem_chunk); - g_unlock(array_mem_chunk); + g_unlock (array_mem_chunk); array->data = NULL; array->len = 0; @@ -81,9 +81,9 @@ g_array_free (GArray *array, if (free_segment) g_free (array->data); - g_lock(array_mem_chunk); + g_lock (array_mem_chunk); g_mem_chunk_free (array_mem_chunk, array); - g_unlock(array_mem_chunk); + g_unlock (array_mem_chunk); } GArray* @@ -258,14 +258,14 @@ g_ptr_array_new (void) { GRealPtrArray *array; - g_lock(ptr_array_mem_chunk); + g_lock (ptr_array_mem_chunk); if (!ptr_array_mem_chunk) ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk", sizeof (GRealPtrArray), 1024, G_ALLOC_AND_FREE); array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk); - g_unlock(ptr_array_mem_chunk); + g_unlock (ptr_array_mem_chunk); array->pdata = NULL; array->len = 0; @@ -283,9 +283,9 @@ g_ptr_array_free (GPtrArray *array, if (free_segment) g_free (array->pdata); - g_lock(ptr_array_mem_chunk); + g_lock (ptr_array_mem_chunk); g_mem_chunk_free (ptr_array_mem_chunk, array); - g_unlock(ptr_array_mem_chunk); + g_unlock (ptr_array_mem_chunk); } static void diff --git a/gcache.c b/gcache.c index e5394f5f7..800bb2b13 100644 --- a/gcache.c +++ b/gcache.c @@ -198,13 +198,13 @@ g_cache_node_new (gpointer value) { GCacheNode *node; - g_lock(node_mem_chunk); + g_lock (node_mem_chunk); if (!node_mem_chunk) node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode), 1024, G_ALLOC_AND_FREE); node = g_chunk_new (GCacheNode, node_mem_chunk); - g_unlock(node_mem_chunk); + g_unlock (node_mem_chunk); node->value = value; node->ref_count = 1; @@ -215,7 +215,7 @@ g_cache_node_new (gpointer value) static void g_cache_node_destroy (GCacheNode *node) { - g_lock(node_mem_chunk); + g_lock (node_mem_chunk); g_mem_chunk_free (node_mem_chunk, node); - g_unlock(node_mem_chunk); + g_unlock (node_mem_chunk); } diff --git a/gdataset.c b/gdataset.c index f4366afc3..f22b21d59 100644 --- a/gdataset.c +++ b/gdataset.c @@ -54,8 +54,6 @@ struct _GDataset /* --- prototypes --- */ -/* all of the following static functions must be called, while holding - the g_dataset_global lock */ static inline GDataset* g_dataset_lookup (gconstpointer dataset_location); static inline void g_datalist_clear_i (GData **datalist); static void g_dataset_destroy_internal (GDataset *dataset); @@ -65,8 +63,6 @@ static inline void g_data_set_internal (GData **datalist, GDestroyNotify destroy_func, GDataset *dataset); static void g_data_initialize (void); -/* the following static function must be called, while holding the - g_quark_global lock */ static inline GQuark g_quark_new (gchar *string); @@ -87,6 +83,8 @@ static GQuark g_quark_seq_id = 0; /* --- functions --- */ + +/* HOLDS: g_dataset_global_lock */ static inline void g_datalist_clear_i (GData **datalist) { @@ -123,15 +121,16 @@ g_datalist_clear (GData **datalist) { g_return_if_fail (datalist != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (!g_dataset_location_ht) g_data_initialize (); while (*datalist) g_datalist_clear_i (datalist); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } +/* HOLDS: g_dataset_global_lock */ static inline GDataset* g_dataset_lookup (gconstpointer dataset_location) { @@ -147,6 +146,7 @@ g_dataset_lookup (gconstpointer dataset_location) return dataset; } +/* HOLDS: g_dataset_global_lock */ static void g_dataset_destroy_internal (GDataset *dataset) { @@ -174,7 +174,7 @@ g_dataset_destroy (gconstpointer dataset_location) { g_return_if_fail (dataset_location != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (g_dataset_location_ht) { register GDataset *dataset; @@ -183,9 +183,10 @@ g_dataset_destroy (gconstpointer dataset_location) if (dataset) g_dataset_destroy_internal (dataset); } - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } +/* HOLDS: g_dataset_global_lock */ static inline void g_data_set_internal (GData **datalist, GQuark key_id, @@ -311,7 +312,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location, return; } - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (!g_dataset_location_ht) g_data_initialize (); @@ -327,7 +328,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location, } g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } void @@ -347,12 +348,12 @@ g_datalist_id_set_data_full (GData **datalist, return; } - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (!g_dataset_location_ht) g_data_initialize (); g_data_set_internal (datalist, key_id, data, destroy_func, NULL); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } void @@ -361,7 +362,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location, { g_return_if_fail (dataset_location != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (key_id && g_dataset_location_ht) { GDataset *dataset; @@ -370,7 +371,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location, if (dataset) g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset); } - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } void @@ -379,10 +380,10 @@ g_datalist_id_remove_no_notify (GData **datalist, { g_return_if_fail (datalist != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (key_id && g_dataset_location_ht) g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } gpointer @@ -391,7 +392,7 @@ g_dataset_id_get_data (gconstpointer dataset_location, { g_return_val_if_fail (dataset_location != NULL, NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (key_id && g_dataset_location_ht) { register GDataset *dataset; @@ -404,12 +405,12 @@ g_dataset_id_get_data (gconstpointer dataset_location, for (list = dataset->datalist; list; list = list->next) if (list->id == key_id) { - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); return list->data; } } } - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); return NULL; } @@ -442,11 +443,11 @@ g_dataset_foreach (gconstpointer dataset_location, g_return_if_fail (dataset_location != NULL); g_return_if_fail (func != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (g_dataset_location_ht) { dataset = g_dataset_lookup (dataset_location); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); if (dataset) { register GData *list; @@ -457,7 +458,7 @@ g_dataset_foreach (gconstpointer dataset_location, } else { - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } } @@ -483,6 +484,7 @@ g_datalist_init (GData **datalist) *datalist = NULL; } +/* HOLDS: g_dataset_global_lock */ static void g_data_initialize (void) { @@ -508,10 +510,10 @@ g_quark_try_string (const gchar *string) GQuark quark = 0; g_return_val_if_fail (string != NULL, 0); - g_lock(g_quark_global); + g_lock (g_quark_global); if (g_quark_ht) quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); - g_unlock(g_quark_global); + g_unlock (g_quark_global); return quark; } @@ -523,7 +525,7 @@ g_quark_from_string (const gchar *string) g_return_val_if_fail (string != NULL, 0); - g_lock(g_quark_global); + g_lock (g_quark_global); if (g_quark_ht) quark = (gulong) g_hash_table_lookup (g_quark_ht, string); else @@ -534,7 +536,7 @@ g_quark_from_string (const gchar *string) if (!quark) quark = g_quark_new (g_strdup (string)); - g_unlock(g_quark_global); + g_unlock (g_quark_global); return quark; } @@ -546,7 +548,7 @@ g_quark_from_static_string (const gchar *string) g_return_val_if_fail (string != NULL, 0); - g_lock(g_quark_global); + g_lock (g_quark_global); if (g_quark_ht) quark = (gulong) g_hash_table_lookup (g_quark_ht, string); else @@ -557,7 +559,7 @@ g_quark_from_static_string (const gchar *string) if (!quark) quark = g_quark_new ((gchar*) string); - g_unlock(g_quark_global); + g_unlock (g_quark_global); return quark; } @@ -566,14 +568,15 @@ gchar* g_quark_to_string (GQuark quark) { gchar* result = NULL; - g_lock(g_quark_global); + g_lock (g_quark_global); if (quark > 0 && quark <= g_quark_seq_id) result = g_quarks[quark - 1]; - g_unlock(g_quark_global); + g_unlock (g_quark_global); return result; } +/* HOLDS: g_quark_global_lock */ static inline GQuark g_quark_new (gchar *string) { diff --git a/gdate.c b/gdate.c index 869920c09..7c60e23d9 100644 --- a/gdate.c +++ b/gdate.c @@ -388,7 +388,7 @@ g_date_clear (GDate *d, guint ndates) memset (d, 0x0, ndates*sizeof (GDate)); } -static G_LOCK_DEFINE(gdate_global); +static G_LOCK_DEFINE(g_date_global); /* These are for the parser, output to the user should use * * g_date_strftime () - this creates more never-freed memory to annoy @@ -436,7 +436,7 @@ typedef struct _GDateParseTokens GDateParseTokens; #define NUM_LEN 10 -/* must be called, while holding the gdate_global lock */ +/* HOLDS: g_date_global_lock */ static void g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt) { @@ -516,7 +516,7 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt) } } -/* must be called, while holding the gdate_global lock */ +/* HOLDS: g_date_global_lock */ static void g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt) { @@ -650,7 +650,7 @@ g_date_set_parse (GDate *d, /* set invalid */ g_date_clear (d, 1); - g_lock(gdate_global); + g_lock (g_date_global); g_date_prepare_to_parse (str, &pt); @@ -662,7 +662,7 @@ g_date_set_parse (GDate *d, if (pt.num_ints == 4) { - g_unlock(gdate_global); + g_unlock (g_date_global); return; /* presumably a typo; bail out. */ } @@ -780,7 +780,7 @@ g_date_set_parse (GDate *d, else g_message ("Rejected DMY %u %u %u", day, m, y); #endif - g_unlock(gdate_global); + g_unlock (g_date_global); } void diff --git a/ghash.c b/ghash.c index eda023d56..724036388 100644 --- a/ghash.c +++ b/ghash.c @@ -57,7 +57,7 @@ static void g_hash_node_destroy (GHashNode *hash_node); static void g_hash_nodes_destroy (GHashNode *hash_node); -static G_LOCK_DEFINE(ghash_global); +static G_LOCK_DEFINE(g_hash_global); static GMemChunk *node_mem_chunk = NULL; static GHashNode *node_free_list = NULL; @@ -345,7 +345,7 @@ g_hash_node_new (gpointer key, { GHashNode *hash_node; - g_lock(ghash_global); + g_lock (g_hash_global); if (node_free_list) { hash_node = node_free_list; @@ -360,7 +360,7 @@ g_hash_node_new (gpointer key, hash_node = g_chunk_new (GHashNode, node_mem_chunk); } - g_unlock(ghash_global); + g_unlock (g_hash_global); hash_node->key = key; hash_node->value = value; @@ -372,10 +372,10 @@ g_hash_node_new (gpointer key, static void g_hash_node_destroy (GHashNode *hash_node) { - g_lock(ghash_global); + g_lock (g_hash_global); hash_node->next = node_free_list; node_free_list = hash_node; - g_unlock(ghash_global); + g_unlock (g_hash_global); } static void @@ -391,8 +391,8 @@ g_hash_nodes_destroy (GHashNode *hash_node) while (node->next) node = node->next; - g_lock(ghash_global); + g_lock (g_hash_global); node->next = node_free_list; node_free_list = hash_node; - g_unlock(ghash_global); + g_unlock (g_hash_global); } diff --git a/glib.h b/glib.h index 8389bc3c2..66263ced1 100644 --- a/glib.h +++ b/glib.h @@ -2612,7 +2612,7 @@ struct _GThreadFunctions { GMutex* (*mutex_new) (); void (*mutex_lock) (GMutex* mutex); - gboolean (*mutex_try_lock) (GMutex* mutex); + gboolean (*mutex_trylock) (GMutex* mutex); void (*mutex_unlock) (GMutex* mutex); void (*mutex_free) (GMutex* mutex); GCond* (*cond_new) (); @@ -2655,7 +2655,7 @@ GMutex* g_static_mutex_get_mutex_impl(GMutex** mutex); recursive in general, don't rely on that */ #define g_mutex_new() G_USE_THREAD_FUNC(mutex_new,NULL,()) #define g_mutex_lock(mutex) G_USE_THREAD_FUNC(mutex_lock,(void)0,(mutex)) -#define g_mutex_try_lock(mutex) G_USE_THREAD_FUNC(mutex_try_lock,TRUE,(mutex)) +#define g_mutex_trylock(mutex) G_USE_THREAD_FUNC(mutex_trylock,TRUE,(mutex)) #define g_mutex_unlock(mutex) G_USE_THREAD_FUNC(mutex_unlock,(void)0,(mutex)) #define g_mutex_free(mutex) G_USE_THREAD_FUNC(mutex_free,(void)0,(mutex)) #define g_cond_new() G_USE_THREAD_FUNC(cond_new,NULL,()) @@ -2680,36 +2680,16 @@ GMutex* g_static_mutex_get_mutex_impl(GMutex** mutex); use */ #define g_static_mutex_lock(mutex) \ g_mutex_lock( g_static_mutex_get_mutex(mutex) ) -#define g_static_mutex_try_lock(mutex) \ - g_mutex_try_lock( g_static_mutex_get_mutex(mutex) ) +#define g_static_mutex_trylock(mutex) \ + g_mutex_trylock( g_static_mutex_get_mutex(mutex) ) #define g_static_mutex_unlock(mutex) \ g_mutex_unlock( g_static_mutex_get_mutex(mutex) ) struct _GStaticPrivate { guint index; - -#if 0 - /* constructor is called by g_private_get */ - GNewFunc constructor; - /* destructor is called, when the thread ends */ - GDestroyNotify destructor; - /* if size is non-zero, constructor is taken to be g_malloc0(size) - and destructor is g_free */ - guint size; - /* do not use the following element */ - guint id; -#endif }; -#if 0 -#define G_STATIC_PRIVATE_INIT_FOR_SIZE(size) \ - { NULL, NULL, size, 0 } - -#define G_STATIC_PRIVATE_INIT_FOR_TYPE(constructor,destructor) \ - { constructor, destructor, 0, 0 } -#endif - #define G_STATIC_PRIVATE_INIT { 0 } gpointer g_static_private_get (GStaticPrivate* private); @@ -2753,12 +2733,11 @@ void g_static_private_set (GStaticPrivate *private, __LINE__, \ __PRETTY_FUNCTION__, \ #name); \ - g_static_mutex_unlock(g_lock_name(name)); \ - }G_STMT_END + }G_STMT_END, g_static_mutex_trylock(g_lock_name(name)) #else /* !G_DEBUG_LOCKS */ #define g_lock(name) g_static_mutex_lock(g_lock_name(name)) #define g_unlock(name) g_static_mutex_unlock(g_lock_name(name)) -#define g_trylock(name) g_static_mutex_try_lock(g_lock_name(name)) +#define g_trylock(name) g_static_mutex_trylock(g_lock_name(name)) #endif #ifdef __cplusplus diff --git a/glib/garray.c b/glib/garray.c index 2bfc91da9..7f0803e3e 100644 --- a/glib/garray.c +++ b/glib/garray.c @@ -55,14 +55,14 @@ g_array_new (gboolean zero_terminated, { GRealArray *array; - g_lock(array_mem_chunk); + g_lock (array_mem_chunk); if (!array_mem_chunk) array_mem_chunk = g_mem_chunk_new ("array mem chunk", sizeof (GRealArray), 1024, G_ALLOC_AND_FREE); array = g_chunk_new (GRealArray, array_mem_chunk); - g_unlock(array_mem_chunk); + g_unlock (array_mem_chunk); array->data = NULL; array->len = 0; @@ -81,9 +81,9 @@ g_array_free (GArray *array, if (free_segment) g_free (array->data); - g_lock(array_mem_chunk); + g_lock (array_mem_chunk); g_mem_chunk_free (array_mem_chunk, array); - g_unlock(array_mem_chunk); + g_unlock (array_mem_chunk); } GArray* @@ -258,14 +258,14 @@ g_ptr_array_new (void) { GRealPtrArray *array; - g_lock(ptr_array_mem_chunk); + g_lock (ptr_array_mem_chunk); if (!ptr_array_mem_chunk) ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk", sizeof (GRealPtrArray), 1024, G_ALLOC_AND_FREE); array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk); - g_unlock(ptr_array_mem_chunk); + g_unlock (ptr_array_mem_chunk); array->pdata = NULL; array->len = 0; @@ -283,9 +283,9 @@ g_ptr_array_free (GPtrArray *array, if (free_segment) g_free (array->pdata); - g_lock(ptr_array_mem_chunk); + g_lock (ptr_array_mem_chunk); g_mem_chunk_free (ptr_array_mem_chunk, array); - g_unlock(ptr_array_mem_chunk); + g_unlock (ptr_array_mem_chunk); } static void diff --git a/glib/gcache.c b/glib/gcache.c index e5394f5f7..800bb2b13 100644 --- a/glib/gcache.c +++ b/glib/gcache.c @@ -198,13 +198,13 @@ g_cache_node_new (gpointer value) { GCacheNode *node; - g_lock(node_mem_chunk); + g_lock (node_mem_chunk); if (!node_mem_chunk) node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode), 1024, G_ALLOC_AND_FREE); node = g_chunk_new (GCacheNode, node_mem_chunk); - g_unlock(node_mem_chunk); + g_unlock (node_mem_chunk); node->value = value; node->ref_count = 1; @@ -215,7 +215,7 @@ g_cache_node_new (gpointer value) static void g_cache_node_destroy (GCacheNode *node) { - g_lock(node_mem_chunk); + g_lock (node_mem_chunk); g_mem_chunk_free (node_mem_chunk, node); - g_unlock(node_mem_chunk); + g_unlock (node_mem_chunk); } diff --git a/glib/gdataset.c b/glib/gdataset.c index f4366afc3..f22b21d59 100644 --- a/glib/gdataset.c +++ b/glib/gdataset.c @@ -54,8 +54,6 @@ struct _GDataset /* --- prototypes --- */ -/* all of the following static functions must be called, while holding - the g_dataset_global lock */ static inline GDataset* g_dataset_lookup (gconstpointer dataset_location); static inline void g_datalist_clear_i (GData **datalist); static void g_dataset_destroy_internal (GDataset *dataset); @@ -65,8 +63,6 @@ static inline void g_data_set_internal (GData **datalist, GDestroyNotify destroy_func, GDataset *dataset); static void g_data_initialize (void); -/* the following static function must be called, while holding the - g_quark_global lock */ static inline GQuark g_quark_new (gchar *string); @@ -87,6 +83,8 @@ static GQuark g_quark_seq_id = 0; /* --- functions --- */ + +/* HOLDS: g_dataset_global_lock */ static inline void g_datalist_clear_i (GData **datalist) { @@ -123,15 +121,16 @@ g_datalist_clear (GData **datalist) { g_return_if_fail (datalist != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (!g_dataset_location_ht) g_data_initialize (); while (*datalist) g_datalist_clear_i (datalist); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } +/* HOLDS: g_dataset_global_lock */ static inline GDataset* g_dataset_lookup (gconstpointer dataset_location) { @@ -147,6 +146,7 @@ g_dataset_lookup (gconstpointer dataset_location) return dataset; } +/* HOLDS: g_dataset_global_lock */ static void g_dataset_destroy_internal (GDataset *dataset) { @@ -174,7 +174,7 @@ g_dataset_destroy (gconstpointer dataset_location) { g_return_if_fail (dataset_location != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (g_dataset_location_ht) { register GDataset *dataset; @@ -183,9 +183,10 @@ g_dataset_destroy (gconstpointer dataset_location) if (dataset) g_dataset_destroy_internal (dataset); } - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } +/* HOLDS: g_dataset_global_lock */ static inline void g_data_set_internal (GData **datalist, GQuark key_id, @@ -311,7 +312,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location, return; } - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (!g_dataset_location_ht) g_data_initialize (); @@ -327,7 +328,7 @@ g_dataset_id_set_data_full (gconstpointer dataset_location, } g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } void @@ -347,12 +348,12 @@ g_datalist_id_set_data_full (GData **datalist, return; } - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (!g_dataset_location_ht) g_data_initialize (); g_data_set_internal (datalist, key_id, data, destroy_func, NULL); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } void @@ -361,7 +362,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location, { g_return_if_fail (dataset_location != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (key_id && g_dataset_location_ht) { GDataset *dataset; @@ -370,7 +371,7 @@ g_dataset_id_remove_no_notify (gconstpointer dataset_location, if (dataset) g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset); } - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } void @@ -379,10 +380,10 @@ g_datalist_id_remove_no_notify (GData **datalist, { g_return_if_fail (datalist != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (key_id && g_dataset_location_ht) g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } gpointer @@ -391,7 +392,7 @@ g_dataset_id_get_data (gconstpointer dataset_location, { g_return_val_if_fail (dataset_location != NULL, NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (key_id && g_dataset_location_ht) { register GDataset *dataset; @@ -404,12 +405,12 @@ g_dataset_id_get_data (gconstpointer dataset_location, for (list = dataset->datalist; list; list = list->next) if (list->id == key_id) { - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); return list->data; } } } - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); return NULL; } @@ -442,11 +443,11 @@ g_dataset_foreach (gconstpointer dataset_location, g_return_if_fail (dataset_location != NULL); g_return_if_fail (func != NULL); - g_lock(g_dataset_global); + g_lock (g_dataset_global); if (g_dataset_location_ht) { dataset = g_dataset_lookup (dataset_location); - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); if (dataset) { register GData *list; @@ -457,7 +458,7 @@ g_dataset_foreach (gconstpointer dataset_location, } else { - g_unlock(g_dataset_global); + g_unlock (g_dataset_global); } } @@ -483,6 +484,7 @@ g_datalist_init (GData **datalist) *datalist = NULL; } +/* HOLDS: g_dataset_global_lock */ static void g_data_initialize (void) { @@ -508,10 +510,10 @@ g_quark_try_string (const gchar *string) GQuark quark = 0; g_return_val_if_fail (string != NULL, 0); - g_lock(g_quark_global); + g_lock (g_quark_global); if (g_quark_ht) quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); - g_unlock(g_quark_global); + g_unlock (g_quark_global); return quark; } @@ -523,7 +525,7 @@ g_quark_from_string (const gchar *string) g_return_val_if_fail (string != NULL, 0); - g_lock(g_quark_global); + g_lock (g_quark_global); if (g_quark_ht) quark = (gulong) g_hash_table_lookup (g_quark_ht, string); else @@ -534,7 +536,7 @@ g_quark_from_string (const gchar *string) if (!quark) quark = g_quark_new (g_strdup (string)); - g_unlock(g_quark_global); + g_unlock (g_quark_global); return quark; } @@ -546,7 +548,7 @@ g_quark_from_static_string (const gchar *string) g_return_val_if_fail (string != NULL, 0); - g_lock(g_quark_global); + g_lock (g_quark_global); if (g_quark_ht) quark = (gulong) g_hash_table_lookup (g_quark_ht, string); else @@ -557,7 +559,7 @@ g_quark_from_static_string (const gchar *string) if (!quark) quark = g_quark_new ((gchar*) string); - g_unlock(g_quark_global); + g_unlock (g_quark_global); return quark; } @@ -566,14 +568,15 @@ gchar* g_quark_to_string (GQuark quark) { gchar* result = NULL; - g_lock(g_quark_global); + g_lock (g_quark_global); if (quark > 0 && quark <= g_quark_seq_id) result = g_quarks[quark - 1]; - g_unlock(g_quark_global); + g_unlock (g_quark_global); return result; } +/* HOLDS: g_quark_global_lock */ static inline GQuark g_quark_new (gchar *string) { diff --git a/glib/gdate.c b/glib/gdate.c index 869920c09..7c60e23d9 100644 --- a/glib/gdate.c +++ b/glib/gdate.c @@ -388,7 +388,7 @@ g_date_clear (GDate *d, guint ndates) memset (d, 0x0, ndates*sizeof (GDate)); } -static G_LOCK_DEFINE(gdate_global); +static G_LOCK_DEFINE(g_date_global); /* These are for the parser, output to the user should use * * g_date_strftime () - this creates more never-freed memory to annoy @@ -436,7 +436,7 @@ typedef struct _GDateParseTokens GDateParseTokens; #define NUM_LEN 10 -/* must be called, while holding the gdate_global lock */ +/* HOLDS: g_date_global_lock */ static void g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt) { @@ -516,7 +516,7 @@ g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt) } } -/* must be called, while holding the gdate_global lock */ +/* HOLDS: g_date_global_lock */ static void g_date_prepare_to_parse (const gchar *str, GDateParseTokens *pt) { @@ -650,7 +650,7 @@ g_date_set_parse (GDate *d, /* set invalid */ g_date_clear (d, 1); - g_lock(gdate_global); + g_lock (g_date_global); g_date_prepare_to_parse (str, &pt); @@ -662,7 +662,7 @@ g_date_set_parse (GDate *d, if (pt.num_ints == 4) { - g_unlock(gdate_global); + g_unlock (g_date_global); return; /* presumably a typo; bail out. */ } @@ -780,7 +780,7 @@ g_date_set_parse (GDate *d, else g_message ("Rejected DMY %u %u %u", day, m, y); #endif - g_unlock(gdate_global); + g_unlock (g_date_global); } void diff --git a/glib/ghash.c b/glib/ghash.c index eda023d56..724036388 100644 --- a/glib/ghash.c +++ b/glib/ghash.c @@ -57,7 +57,7 @@ static void g_hash_node_destroy (GHashNode *hash_node); static void g_hash_nodes_destroy (GHashNode *hash_node); -static G_LOCK_DEFINE(ghash_global); +static G_LOCK_DEFINE(g_hash_global); static GMemChunk *node_mem_chunk = NULL; static GHashNode *node_free_list = NULL; @@ -345,7 +345,7 @@ g_hash_node_new (gpointer key, { GHashNode *hash_node; - g_lock(ghash_global); + g_lock (g_hash_global); if (node_free_list) { hash_node = node_free_list; @@ -360,7 +360,7 @@ g_hash_node_new (gpointer key, hash_node = g_chunk_new (GHashNode, node_mem_chunk); } - g_unlock(ghash_global); + g_unlock (g_hash_global); hash_node->key = key; hash_node->value = value; @@ -372,10 +372,10 @@ g_hash_node_new (gpointer key, static void g_hash_node_destroy (GHashNode *hash_node) { - g_lock(ghash_global); + g_lock (g_hash_global); hash_node->next = node_free_list; node_free_list = hash_node; - g_unlock(ghash_global); + g_unlock (g_hash_global); } static void @@ -391,8 +391,8 @@ g_hash_nodes_destroy (GHashNode *hash_node) while (node->next) node = node->next; - g_lock(ghash_global); + g_lock (g_hash_global); node->next = node_free_list; node_free_list = hash_node; - g_unlock(ghash_global); + g_unlock (g_hash_global); } diff --git a/glib/glib.h b/glib/glib.h index 8389bc3c2..66263ced1 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -2612,7 +2612,7 @@ struct _GThreadFunctions { GMutex* (*mutex_new) (); void (*mutex_lock) (GMutex* mutex); - gboolean (*mutex_try_lock) (GMutex* mutex); + gboolean (*mutex_trylock) (GMutex* mutex); void (*mutex_unlock) (GMutex* mutex); void (*mutex_free) (GMutex* mutex); GCond* (*cond_new) (); @@ -2655,7 +2655,7 @@ GMutex* g_static_mutex_get_mutex_impl(GMutex** mutex); recursive in general, don't rely on that */ #define g_mutex_new() G_USE_THREAD_FUNC(mutex_new,NULL,()) #define g_mutex_lock(mutex) G_USE_THREAD_FUNC(mutex_lock,(void)0,(mutex)) -#define g_mutex_try_lock(mutex) G_USE_THREAD_FUNC(mutex_try_lock,TRUE,(mutex)) +#define g_mutex_trylock(mutex) G_USE_THREAD_FUNC(mutex_trylock,TRUE,(mutex)) #define g_mutex_unlock(mutex) G_USE_THREAD_FUNC(mutex_unlock,(void)0,(mutex)) #define g_mutex_free(mutex) G_USE_THREAD_FUNC(mutex_free,(void)0,(mutex)) #define g_cond_new() G_USE_THREAD_FUNC(cond_new,NULL,()) @@ -2680,36 +2680,16 @@ GMutex* g_static_mutex_get_mutex_impl(GMutex** mutex); use */ #define g_static_mutex_lock(mutex) \ g_mutex_lock( g_static_mutex_get_mutex(mutex) ) -#define g_static_mutex_try_lock(mutex) \ - g_mutex_try_lock( g_static_mutex_get_mutex(mutex) ) +#define g_static_mutex_trylock(mutex) \ + g_mutex_trylock( g_static_mutex_get_mutex(mutex) ) #define g_static_mutex_unlock(mutex) \ g_mutex_unlock( g_static_mutex_get_mutex(mutex) ) struct _GStaticPrivate { guint index; - -#if 0 - /* constructor is called by g_private_get */ - GNewFunc constructor; - /* destructor is called, when the thread ends */ - GDestroyNotify destructor; - /* if size is non-zero, constructor is taken to be g_malloc0(size) - and destructor is g_free */ - guint size; - /* do not use the following element */ - guint id; -#endif }; -#if 0 -#define G_STATIC_PRIVATE_INIT_FOR_SIZE(size) \ - { NULL, NULL, size, 0 } - -#define G_STATIC_PRIVATE_INIT_FOR_TYPE(constructor,destructor) \ - { constructor, destructor, 0, 0 } -#endif - #define G_STATIC_PRIVATE_INIT { 0 } gpointer g_static_private_get (GStaticPrivate* private); @@ -2753,12 +2733,11 @@ void g_static_private_set (GStaticPrivate *private, __LINE__, \ __PRETTY_FUNCTION__, \ #name); \ - g_static_mutex_unlock(g_lock_name(name)); \ - }G_STMT_END + }G_STMT_END, g_static_mutex_trylock(g_lock_name(name)) #else /* !G_DEBUG_LOCKS */ #define g_lock(name) g_static_mutex_lock(g_lock_name(name)) #define g_unlock(name) g_static_mutex_unlock(g_lock_name(name)) -#define g_trylock(name) g_static_mutex_try_lock(g_lock_name(name)) +#define g_trylock(name) g_static_mutex_trylock(g_lock_name(name)) #endif #ifdef __cplusplus diff --git a/glib/glist.c b/glib/glist.c index 253002639..77c269aff 100644 --- a/glib/glist.c +++ b/glib/glist.c @@ -38,6 +38,7 @@ struct _GAllocator /* from gmem.c */ static GAllocator *current_allocator = NULL; static G_LOCK_DEFINE(current_allocator); +/* HOLDS: current_allocator_lock */ static void g_list_validate_allocator (GAllocator *allocator) { @@ -70,16 +71,16 @@ void g_list_push_allocator(GAllocator *allocator) { g_list_validate_allocator ( allocator ); - g_lock(current_allocator); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; - g_unlock(current_allocator); + g_unlock (current_allocator); } void g_list_pop_allocator (void) { - g_lock(current_allocator); + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -89,7 +90,7 @@ g_list_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } - g_unlock(current_allocator); + g_unlock (current_allocator); } GList* @@ -97,12 +98,12 @@ g_list_alloc (void) { GList *list; - g_lock(current_allocator); + g_lock (current_allocator); if (!current_allocator) { GAllocator *allocator = g_allocator_new ("GLib default GList allocator", 1024); - g_list_validate_allocator ( allocator ); + g_list_validate_allocator (allocator); allocator->last = NULL; current_allocator = allocator; } @@ -125,7 +126,7 @@ g_list_alloc (void) current_allocator->free_lists = list->next; } } - g_unlock(current_allocator); + g_unlock (current_allocator); list->next = NULL; list->prev = NULL; @@ -138,10 +139,10 @@ g_list_free (GList *list) if (list) { list->data = list->next; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } @@ -151,10 +152,10 @@ g_list_free_1 (GList *list) if (list) { list->data = NULL; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } diff --git a/glib/gmain.c b/glib/gmain.c index 6fd427bf2..5d3ae8d46 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -20,6 +20,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ + #include "glib.h" #include #include @@ -97,7 +101,7 @@ static GHookList source_list = { 0 }; /* The following lock is used for both the list of sources * and the list of poll records */ -G_LOCK_DEFINE (main_loop); +static G_LOCK_DEFINE (main_loop); static GSourceFuncs timeout_funcs = { g_timeout_prepare, @@ -228,7 +232,7 @@ g_source_add (gint priority, guint return_val; GSource *source; - g_lock(main_loop); + g_lock (main_loop); if (!source_list.is_setup) g_hook_list_init (&source_list, sizeof(GSource)); @@ -257,7 +261,7 @@ g_source_add (gint priority, write (wake_up_pipe[1], "A", 1); } - g_unlock(main_loop); + g_unlock (main_loop); return return_val; } @@ -601,10 +605,10 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority) poll_waiting = TRUE; - g_unlock(main_loop); + g_unlock (main_loop); npoll = i; (*poll_func) (fd_array, npoll, timeout); - g_lock(main_loop); + g_lock (main_loop); if (!poll_waiting) { @@ -644,7 +648,14 @@ g_main_poll_add_unlocked (gint priority, if (!poll_chunk) poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY); - newrec = g_chunk_new (GPollRec, poll_chunk); + if (poll_free_list) + { + newrec = poll_free_list; + poll_free_list = newrec->next; + } + else + newrec = g_chunk_new (GPollRec, poll_chunk); + newrec->fd = fd; newrec->priority = priority; @@ -697,7 +708,7 @@ g_main_poll_remove (GPollFD *fd) pollrec = pollrec->next; } - g_unlock(main_loop); + g_unlock (main_loop); } void diff --git a/glib/gmem.c b/glib/gmem.c index c29ee660f..47a0d1520 100644 --- a/glib/gmem.c +++ b/glib/gmem.c @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -48,8 +52,14 @@ */ #if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS) -#define ENTER_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk++ -#define LEAVE_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk-- +#define ENTER_MEM_CHUNK_ROUTINE() \ + g_static_private_set (allocating_for_mem_chunk, \ + g_static_private_get (allocating_for_mem_chunk) + 1, \ + NULL) +#define ENTER_MEM_CHUNK_ROUTINE() \ + g_static_private_set (allocating_for_mem_chunk, \ + g_static_private_get (allocating_for_mem_chunk) - 1, \ + NULL) #else #define ENTER_MEM_CHUNK_ROUTINE() #define LEAVE_MEM_CHUNK_ROUTINE() @@ -117,13 +127,17 @@ static gint g_mem_chunk_area_search (GMemArea *a, gchar *addr); +static G_LOCK_DEFINE(mem_chunks); static GRealMemChunk *mem_chunks = NULL; #ifdef ENABLE_MEM_PROFILE +static G_LOCK_DEFINE(mem_profile); static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 }; static gulong allocated_mem = 0; static gulong freed_mem = 0; -static gint allocating_for_mem_chunk = 0; +static GStaticPrivate allocating_for_mem_chunk = G_STATIC_PRIVATE_INIT; +#define IS_IN_MEM_CHUNK_ROUTINE() \ + GPOINTER_TO_UINT (g_static_private_get (allocating_for_mem_chunk)) #endif /* ENABLE_MEM_PROFILE */ @@ -174,8 +188,9 @@ g_malloc (gulong size) *t = size; #ifdef ENABLE_MEM_PROFILE + g_lock(mem_profile); # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS - if(!allocating_for_mem_chunk) { + if(!IS_IN_MEM_CHUNK_ROUTINE()) { # endif if (size <= MEM_PROFILE_TABLE_SIZE - 1) allocations[size-1] += 1; @@ -185,6 +200,7 @@ g_malloc (gulong size) # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS } # endif + g_unlock(mem_profile); #endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -237,8 +253,9 @@ g_malloc0 (gulong size) *t = size; # ifdef ENABLE_MEM_PROFILE + g_lock(mem_profile); # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS - if(!allocating_for_mem_chunk) { + if(!IS_IN_MEM_CHUNK_ROUTINE()) { # endif if (size <= (MEM_PROFILE_TABLE_SIZE - 1)) allocations[size-1] += 1; @@ -248,8 +265,9 @@ g_malloc0 (gulong size) # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS } # endif + g_unlock(mem_profile); # endif /* ENABLE_MEM_PROFILE */ -#endif /* ENABLE_MEM_PROFILE */ +#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ return p; @@ -286,7 +304,9 @@ g_realloc (gpointer mem, #if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK) t = (gulong*) ((guchar*) mem - SIZEOF_LONG); #ifdef ENABLE_MEM_PROFILE + g_lock (mem_profile); freed_mem += *t; + g_unlock (mem_profile); #endif /* ENABLE_MEM_PROFILE */ mem = t; #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -321,8 +341,9 @@ g_realloc (gpointer mem, *t = size; #ifdef ENABLE_MEM_PROFILE + g_lock(mem_profile); #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS - if(!allocating_for_mem_chunk) { + if(!IS_IN_MEM_CHUNK_ROUTINE()) { #endif if (size <= (MEM_PROFILE_TABLE_SIZE - 1)) allocations[size-1] += 1; @@ -332,6 +353,7 @@ g_realloc (gpointer mem, #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS } #endif + g_unlock(mem_profile); #endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -352,8 +374,10 @@ g_free (gpointer mem) #if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK) t = (gulong*) ((guchar*) mem - SIZEOF_LONG); size = *t; -#ifdef ENABLE_MEM_PROFILE +#ifdef ENABLE_MEM_PROFILE + g_lock (mem_profile); freed_mem += size; + g_unlock (mem_profile); #endif /* ENABLE_MEM_PROFILE */ mem = t; #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -380,19 +404,29 @@ g_mem_profile (void) { #ifdef ENABLE_MEM_PROFILE gint i; - + gulong local_allocations[MEM_PROFILE_TABLE_SIZE]; + gulong local_allocated_mem; + gulong local_freed_mem; + + g_lock (mem_profile); for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) - if (allocations[i] > 0) + local_allocations[i] = allocations[i]; + local_allocated_mem = allocated_mem; + local_freed_mem = freed_mem; + g_unlock (mem_profile); + + for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) + if (local_allocations[i] > 0) g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, - "%lu allocations of %d bytes\n", allocations[i], i + 1); + "%lu allocations of %d bytes\n", local_allocations[i], i + 1); - if (allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0) + if (local_allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0) g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu allocations of greater than %d bytes\n", - allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1); - g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", allocated_mem); - g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", freed_mem); - g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", allocated_mem - freed_mem); + local_allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1); + g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", local_allocated_mem); + g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", local_freed_mem); + g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", local_allocated_mem - local_freed_mem); #endif /* ENABLE_MEM_PROFILE */ } @@ -460,11 +494,13 @@ g_mem_chunk_new (gchar *name, mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size); */ + g_lock (mem_chunks); mem_chunk->next = mem_chunks; mem_chunk->prev = NULL; if (mem_chunks) mem_chunks->prev = mem_chunk; mem_chunks = mem_chunk; + g_unlock (mem_chunks); LEAVE_MEM_CHUNK_ROUTINE(); @@ -497,8 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk) if (rmem_chunk->prev) rmem_chunk->prev->next = rmem_chunk->next; + g_lock (mem_chunks); if (rmem_chunk == mem_chunks) mem_chunks = mem_chunks->next; + g_unlock (mem_chunks); if (rmem_chunk->type == G_ALLOC_AND_FREE) g_tree_destroy (rmem_chunk->mem_tree); @@ -826,21 +864,26 @@ g_mem_chunk_info (void) gint count; count = 0; + g_lock (mem_chunks); mem_chunk = mem_chunks; while (mem_chunk) { count += 1; mem_chunk = mem_chunk->next; } + g_unlock (mem_chunks); g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count); + g_lock (mem_chunks); mem_chunk = mem_chunks; + g_unlock (mem_chunks); + while (mem_chunk) { g_mem_chunk_print ((GMemChunk*) mem_chunk); mem_chunk = mem_chunk->next; - } + } } void @@ -848,7 +891,9 @@ g_blow_chunks (void) { GRealMemChunk *mem_chunk; + g_lock (mem_chunks); mem_chunk = mem_chunks; + g_unlock (mem_chunks); while (mem_chunk) { g_mem_chunk_clean ((GMemChunk*) mem_chunk); diff --git a/glib/gmessages.c b/glib/gmessages.c index 963dd921e..46e6d2f4f 100644 --- a/glib/gmessages.c +++ b/glib/gmessages.c @@ -72,7 +72,7 @@ struct _GLogHandler /* --- variables --- */ -static G_LOCK_DEFINE(gmessages_global); +static G_LOCK_DEFINE(g_messages_global); const gchar *g_log_domain_glib = "GLib"; static GLogDomain *g_log_domains = NULL; @@ -92,18 +92,18 @@ g_log_find_domain (const gchar *log_domain) { register GLogDomain *domain; - g_lock (gmessages_global); + g_lock (g_messages_global); domain = g_log_domains; while (domain) { if (strcmp (domain->log_domain, log_domain) == 0) { - g_unlock(gmessages_global); + g_unlock (g_messages_global); return domain; } domain = domain->next; } - g_unlock (gmessages_global); + g_unlock (g_messages_global); return NULL; } @@ -117,10 +117,10 @@ g_log_domain_new (const gchar *log_domain) domain->fatal_mask = G_LOG_FATAL_MASK; domain->handlers = NULL; - g_lock (gmessages_global); + g_lock (g_messages_global); domain->next = g_log_domains; g_log_domains = domain; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return domain; } @@ -135,7 +135,7 @@ g_log_domain_check_free (GLogDomain *domain) last = NULL; - g_lock (gmessages_global); + g_lock (g_messages_global); work = g_log_domains; while (work) { @@ -151,7 +151,7 @@ g_log_domain_check_free (GLogDomain *domain) } work = work->next; } - g_unlock (gmessages_global); + g_unlock (g_messages_global); } } @@ -190,10 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask) /* remove bogus flag */ fatal_mask &= ~G_LOG_FLAG_FATAL; - g_lock (gmessages_global); + g_lock (g_messages_global); old_mask = g_log_always_fatal; g_log_always_fatal = fatal_mask; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_mask; } @@ -245,9 +245,9 @@ g_log_set_handler (const gchar *log_domain, domain = g_log_domain_new (log_domain); handler = g_new (GLogHandler, 1); - g_lock (gmessages_global); + g_lock (g_messages_global); handler->id = ++handler_id; - g_unlock (gmessages_global); + g_unlock (g_messages_global); handler->log_level = log_levels; handler->log_func = log_func; handler->data = user_data; @@ -348,11 +348,11 @@ g_logv (const gchar *log_domain, depth++; g_static_private_set (&g_log_depth, GUINT_TO_POINTER (depth), NULL); - g_lock (gmessages_global); + g_lock (g_messages_global); if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) & test_level) != 0) test_level |= G_LOG_FLAG_FATAL; - g_unlock (gmessages_global); + g_unlock (g_messages_global); log_func = g_log_domain_get_handler (domain, test_level, &data); log_func (log_domain, test_level, buffer, data); @@ -414,11 +414,11 @@ g_log_default_handler (const gchar *log_domain, fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2; #endif - g_lock (gmessages_global); + g_lock (g_messages_global); local_glib_error_func = glib_error_func; local_glib_warning_func = glib_warning_func; local_glib_message_func = glib_message_func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); switch (log_level) { @@ -593,10 +593,10 @@ g_set_print_handler (GPrintFunc func) { GPrintFunc old_print_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_print_func = glib_print_func; glib_print_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_print_func; } @@ -615,9 +615,9 @@ g_print (const gchar *format, string = g_strdup_vprintf (format, args); va_end (args); - g_lock (gmessages_global); + g_lock (g_messages_global); local_glib_print_func = glib_print_func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); if (local_glib_print_func) local_glib_print_func (string); @@ -634,10 +634,10 @@ g_set_printerr_handler (GPrintFunc func) { GPrintFunc old_printerr_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_printerr_func = glib_printerr_func; glib_printerr_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_printerr_func; } @@ -656,9 +656,9 @@ g_printerr (const gchar *format, string = g_strdup_vprintf (format, args); va_end (args); - g_lock (gmessages_global); + g_lock (g_messages_global); local_glib_printerr_func = glib_printerr_func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); if (local_glib_printerr_func) local_glib_printerr_func (string); @@ -676,10 +676,10 @@ g_set_error_handler (GErrorFunc func) { GErrorFunc old_error_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_error_func = glib_error_func; glib_error_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_error_func; } @@ -690,10 +690,10 @@ g_set_warning_handler (GWarningFunc func) { GWarningFunc old_warning_func; - g_lock(gmessages_global); + g_lock (g_messages_global); old_warning_func = glib_warning_func; glib_warning_func = func; - g_unlock(gmessages_global); + g_unlock (g_messages_global); return old_warning_func; } @@ -704,10 +704,10 @@ g_set_message_handler (GPrintFunc func) { GPrintFunc old_message_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_message_func = glib_message_func; glib_message_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_message_func; } diff --git a/glib/gnode.c b/glib/gnode.c index b4d2de424..089a4996d 100644 --- a/glib/gnode.c +++ b/glib/gnode.c @@ -39,9 +39,10 @@ struct _GAllocator /* from gmem.c */ GNode *free_nodes; /* implementation specific */ }; -G_LOCK_DEFINE(current_allocator); +static G_LOCK_DEFINE(current_allocator); static GAllocator *current_allocator = NULL; +/* HOLDS: current_allocator_lock */ static void g_node_validate_allocator (GAllocator *allocator) { @@ -74,16 +75,16 @@ void g_node_push_allocator (GAllocator *allocator) { g_node_validate_allocator ( allocator ); - g_lock(current_allocator); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; - g_unlock(current_allocator); + g_unlock (current_allocator); } void g_node_pop_allocator (void) { - g_lock(current_allocator); + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -93,7 +94,7 @@ g_node_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } - g_unlock(current_allocator); + g_unlock (current_allocator); } @@ -103,12 +104,12 @@ g_node_new (gpointer data) { GNode *node; - g_lock(current_allocator); + g_lock (current_allocator); if (!current_allocator) { GAllocator *allocator = g_allocator_new ("GLib default GNode allocator", 1024); - g_node_validate_allocator ( allocator ); + g_node_validate_allocator (allocator); allocator->last = NULL; current_allocator = allocator; } @@ -119,7 +120,7 @@ g_node_new (gpointer data) node = current_allocator->free_nodes; current_allocator->free_nodes = node->next; } - g_unlock(current_allocator); + g_unlock (current_allocator); node->data = data; node->next = NULL; @@ -146,10 +147,10 @@ g_nodes_free (GNode *node) break; } - g_lock(current_allocator); + g_lock (current_allocator); parent->next = current_allocator->free_nodes; current_allocator->free_nodes = node; - g_unlock(current_allocator); + g_unlock (current_allocator); } void diff --git a/glib/gslist.c b/glib/gslist.c index b7ee371cc..1ed517ff6 100644 --- a/glib/gslist.c +++ b/glib/gslist.c @@ -38,6 +38,7 @@ struct _GAllocator /* from gmem.c */ static G_LOCK_DEFINE(current_allocator); static GAllocator *current_allocator = NULL; +/* HOLDS: current_allocator_lock */ static void g_slist_validate_allocator (GAllocator *allocator) { @@ -70,16 +71,16 @@ void g_slist_push_allocator (GAllocator *allocator) { g_slist_validate_allocator (allocator); - g_lock(current_allocator); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; - g_unlock(current_allocator); + g_unlock (current_allocator); } void g_slist_pop_allocator (void) { - g_lock(current_allocator); + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -89,7 +90,7 @@ g_slist_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } - g_unlock(current_allocator); + g_unlock (current_allocator); } GSList* @@ -97,12 +98,12 @@ g_slist_alloc (void) { GSList *list; - g_lock(current_allocator); + g_lock (current_allocator); if (!current_allocator) { GAllocator *allocator = g_allocator_new ("GLib default GSList allocator", 1024); - g_slist_validate_allocator ( allocator ); + g_slist_validate_allocator (allocator); allocator->last = NULL; current_allocator = allocator; } @@ -125,7 +126,7 @@ g_slist_alloc (void) current_allocator->free_lists = list->next; } } - g_unlock(current_allocator); + g_unlock (current_allocator); list->next = NULL; @@ -138,10 +139,10 @@ g_slist_free (GSList *list) if (list) { list->data = list->next; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } @@ -151,10 +152,10 @@ g_slist_free_1 (GSList *list) if (list) { list->data = NULL; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index ad28978ee..e154c56dc 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -208,7 +212,8 @@ g_strtod (const gchar *nptr, gchar* g_strerror (gint errnum) { - static char msg[64]; + static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; + char *msg; #ifdef HAVE_STRERROR return strerror (errnum); @@ -634,7 +639,14 @@ g_strerror (gint errnum) if ((errnum > 0) && (errnum <= sys_nerr)) return sys_errlist [errnum]; #endif /* NO_SYS_ERRLIST */ - + + msg = g_static_private_get (&msg_private); + if( !msg ) + { + msg = g_new( gchar, 64 ); + g_static_private_set (&msg_private, msg, g_free); + } + sprintf (msg, "unknown error (%d)", errnum); return msg; } @@ -642,7 +654,8 @@ g_strerror (gint errnum) gchar* g_strsignal (gint signum) { - static char msg[64]; + static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; + char *msg; #ifdef HAVE_STRSIGNAL extern char *strsignal (int sig); @@ -748,6 +761,13 @@ g_strsignal (gint signum) extern char *sys_siglist[]; return sys_siglist [signum]; #endif /* NO_SYS_SIGLIST */ + + msg = g_static_private_get (&msg_private); + if( !msg ) + { + msg = g_new( gchar, 64 ); + g_static_private_set (&msg_private, msg, g_free); + } sprintf (msg, "unknown signal (%d)", signum); return msg; diff --git a/glib/gstring.c b/glib/gstring.c index 3983cfc6b..312a54060 100644 --- a/glib/gstring.c +++ b/glib/gstring.c @@ -207,14 +207,14 @@ g_string_sized_new (guint dfl_size) { GRealString *string; - g_lock(string_mem_chunk); + g_lock (string_mem_chunk); if (!string_mem_chunk) string_mem_chunk = g_mem_chunk_new ("string mem chunk", sizeof (GRealString), 1024, G_ALLOC_AND_FREE); string = g_chunk_new (GRealString, string_mem_chunk); - g_unlock(string_mem_chunk); + g_unlock (string_mem_chunk); string->alloc = 0; string->len = 0; @@ -248,9 +248,9 @@ g_string_free (GString *string, if (free_segment) g_free (string->str); - g_unlock(string_mem_chunk); + g_lock (string_mem_chunk); g_mem_chunk_free (string_mem_chunk, string); - g_lock(string_mem_chunk); + g_unlock (string_mem_chunk); } GString* diff --git a/glib/gtree.c b/glib/gtree.c index b1167bc08..006f15db7 100644 --- a/glib/gtree.c +++ b/glib/gtree.c @@ -83,7 +83,7 @@ static GTreeNode* g_tree_node_rotate_right (GTreeNode *node); static void g_tree_node_check (GTreeNode *node); -static G_LOCK_DEFINE(gnode_global); +static G_LOCK_DEFINE(g_tree_global); static GMemChunk *node_mem_chunk = NULL; static GTreeNode *node_free_list = NULL; @@ -94,7 +94,7 @@ g_tree_node_new (gpointer key, { GTreeNode *node; - g_lock(gnode_global); + g_lock (g_tree_global); if (node_free_list) { node = node_free_list; @@ -110,7 +110,7 @@ g_tree_node_new (gpointer key, node = g_chunk_new (GTreeNode, node_mem_chunk); } - g_unlock(gnode_global); + g_unlock (g_tree_global); node->balance = 0; node->left = NULL; @@ -128,10 +128,10 @@ g_tree_node_destroy (GTreeNode *node) { g_tree_node_destroy (node->right); g_tree_node_destroy (node->left); - g_lock(gnode_global); + g_lock (g_tree_global); node->right = node_free_list; node_free_list = node; - g_unlock(gnode_global); + g_unlock (g_tree_global); } } @@ -385,10 +385,10 @@ g_tree_node_remove (GTreeNode *node, node = g_tree_node_restore_right_balance (new_root, old_balance); } - g_lock(gnode_global); + g_lock (g_tree_global); garbage->right = node_free_list; node_free_list = garbage; - g_unlock(gnode_global); + g_unlock (g_tree_global); } else if (cmp < 0) { diff --git a/glib/gutils.c b/glib/gutils.c index cc6594937..9a91199b6 100644 --- a/glib/gutils.c +++ b/glib/gutils.c @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe for the unix part, FIXME: make the win32 part MT safe as well. + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -367,11 +371,14 @@ g_getenv (const gchar *variable) #endif } +static G_LOCK_DEFINE(g_utils_global); + static gchar *g_tmp_dir = NULL; static gchar *g_user_name = NULL; static gchar *g_real_name = NULL; static gchar *g_home_dir = NULL; +/* HOLDS: g_utils_global_lock */ static void g_get_any_init (void) { @@ -442,14 +449,16 @@ g_get_any_init (void) g_home_dir = NULL; # endif /* !NATIVE_WIN32 */ #endif /* !HAVE_PWD_H */ - } + } } gchar* g_get_user_name (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); + g_unlock (g_utils_global); return g_user_name; } @@ -457,9 +466,11 @@ g_get_user_name (void) gchar* g_get_real_name (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); - + g_unlock (g_utils_global); + return g_real_name; } @@ -472,8 +483,10 @@ g_get_real_name (void) gchar* g_get_home_dir (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); + g_unlock (g_utils_global); return g_home_dir; } @@ -488,8 +501,10 @@ g_get_home_dir (void) gchar* g_get_tmp_dir (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); + g_unlock (g_utils_global); return g_tmp_dir; } @@ -499,16 +514,25 @@ static gchar *g_prgname = NULL; gchar* g_get_prgname (void) { - return g_prgname; + gchar* retval; + + g_lock (g_utils_global); + retval = g_prgname; + g_unlock (g_utils_global); + + return retval; } void g_set_prgname (const gchar *prgname) { - gchar *c = g_prgname; - + gchar *c; + + g_lock (g_utils_global); + c = g_prgname; g_prgname = g_strdup (prgname); g_free (c); + g_unlock (g_utils_global); } guint diff --git a/glist.c b/glist.c index 253002639..77c269aff 100644 --- a/glist.c +++ b/glist.c @@ -38,6 +38,7 @@ struct _GAllocator /* from gmem.c */ static GAllocator *current_allocator = NULL; static G_LOCK_DEFINE(current_allocator); +/* HOLDS: current_allocator_lock */ static void g_list_validate_allocator (GAllocator *allocator) { @@ -70,16 +71,16 @@ void g_list_push_allocator(GAllocator *allocator) { g_list_validate_allocator ( allocator ); - g_lock(current_allocator); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; - g_unlock(current_allocator); + g_unlock (current_allocator); } void g_list_pop_allocator (void) { - g_lock(current_allocator); + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -89,7 +90,7 @@ g_list_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } - g_unlock(current_allocator); + g_unlock (current_allocator); } GList* @@ -97,12 +98,12 @@ g_list_alloc (void) { GList *list; - g_lock(current_allocator); + g_lock (current_allocator); if (!current_allocator) { GAllocator *allocator = g_allocator_new ("GLib default GList allocator", 1024); - g_list_validate_allocator ( allocator ); + g_list_validate_allocator (allocator); allocator->last = NULL; current_allocator = allocator; } @@ -125,7 +126,7 @@ g_list_alloc (void) current_allocator->free_lists = list->next; } } - g_unlock(current_allocator); + g_unlock (current_allocator); list->next = NULL; list->prev = NULL; @@ -138,10 +139,10 @@ g_list_free (GList *list) if (list) { list->data = list->next; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } @@ -151,10 +152,10 @@ g_list_free_1 (GList *list) if (list) { list->data = NULL; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } diff --git a/gmain.c b/gmain.c index 6fd427bf2..5d3ae8d46 100644 --- a/gmain.c +++ b/gmain.c @@ -20,6 +20,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ + #include "glib.h" #include #include @@ -97,7 +101,7 @@ static GHookList source_list = { 0 }; /* The following lock is used for both the list of sources * and the list of poll records */ -G_LOCK_DEFINE (main_loop); +static G_LOCK_DEFINE (main_loop); static GSourceFuncs timeout_funcs = { g_timeout_prepare, @@ -228,7 +232,7 @@ g_source_add (gint priority, guint return_val; GSource *source; - g_lock(main_loop); + g_lock (main_loop); if (!source_list.is_setup) g_hook_list_init (&source_list, sizeof(GSource)); @@ -257,7 +261,7 @@ g_source_add (gint priority, write (wake_up_pipe[1], "A", 1); } - g_unlock(main_loop); + g_unlock (main_loop); return return_val; } @@ -601,10 +605,10 @@ g_main_poll (gint timeout, gboolean use_priority, gint priority) poll_waiting = TRUE; - g_unlock(main_loop); + g_unlock (main_loop); npoll = i; (*poll_func) (fd_array, npoll, timeout); - g_lock(main_loop); + g_lock (main_loop); if (!poll_waiting) { @@ -644,7 +648,14 @@ g_main_poll_add_unlocked (gint priority, if (!poll_chunk) poll_chunk = g_mem_chunk_create (GPollRec, 32, G_ALLOC_ONLY); - newrec = g_chunk_new (GPollRec, poll_chunk); + if (poll_free_list) + { + newrec = poll_free_list; + poll_free_list = newrec->next; + } + else + newrec = g_chunk_new (GPollRec, poll_chunk); + newrec->fd = fd; newrec->priority = priority; @@ -697,7 +708,7 @@ g_main_poll_remove (GPollFD *fd) pollrec = pollrec->next; } - g_unlock(main_loop); + g_unlock (main_loop); } void diff --git a/gmem.c b/gmem.c index c29ee660f..47a0d1520 100644 --- a/gmem.c +++ b/gmem.c @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -48,8 +52,14 @@ */ #if defined(ENABLE_MEM_PROFILE) && defined(ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS) -#define ENTER_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk++ -#define LEAVE_MEM_CHUNK_ROUTINE() allocating_for_mem_chunk-- +#define ENTER_MEM_CHUNK_ROUTINE() \ + g_static_private_set (allocating_for_mem_chunk, \ + g_static_private_get (allocating_for_mem_chunk) + 1, \ + NULL) +#define ENTER_MEM_CHUNK_ROUTINE() \ + g_static_private_set (allocating_for_mem_chunk, \ + g_static_private_get (allocating_for_mem_chunk) - 1, \ + NULL) #else #define ENTER_MEM_CHUNK_ROUTINE() #define LEAVE_MEM_CHUNK_ROUTINE() @@ -117,13 +127,17 @@ static gint g_mem_chunk_area_search (GMemArea *a, gchar *addr); +static G_LOCK_DEFINE(mem_chunks); static GRealMemChunk *mem_chunks = NULL; #ifdef ENABLE_MEM_PROFILE +static G_LOCK_DEFINE(mem_profile); static gulong allocations[MEM_PROFILE_TABLE_SIZE] = { 0 }; static gulong allocated_mem = 0; static gulong freed_mem = 0; -static gint allocating_for_mem_chunk = 0; +static GStaticPrivate allocating_for_mem_chunk = G_STATIC_PRIVATE_INIT; +#define IS_IN_MEM_CHUNK_ROUTINE() \ + GPOINTER_TO_UINT (g_static_private_get (allocating_for_mem_chunk)) #endif /* ENABLE_MEM_PROFILE */ @@ -174,8 +188,9 @@ g_malloc (gulong size) *t = size; #ifdef ENABLE_MEM_PROFILE + g_lock(mem_profile); # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS - if(!allocating_for_mem_chunk) { + if(!IS_IN_MEM_CHUNK_ROUTINE()) { # endif if (size <= MEM_PROFILE_TABLE_SIZE - 1) allocations[size-1] += 1; @@ -185,6 +200,7 @@ g_malloc (gulong size) # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS } # endif + g_unlock(mem_profile); #endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -237,8 +253,9 @@ g_malloc0 (gulong size) *t = size; # ifdef ENABLE_MEM_PROFILE + g_lock(mem_profile); # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS - if(!allocating_for_mem_chunk) { + if(!IS_IN_MEM_CHUNK_ROUTINE()) { # endif if (size <= (MEM_PROFILE_TABLE_SIZE - 1)) allocations[size-1] += 1; @@ -248,8 +265,9 @@ g_malloc0 (gulong size) # ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS } # endif + g_unlock(mem_profile); # endif /* ENABLE_MEM_PROFILE */ -#endif /* ENABLE_MEM_PROFILE */ +#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ return p; @@ -286,7 +304,9 @@ g_realloc (gpointer mem, #if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK) t = (gulong*) ((guchar*) mem - SIZEOF_LONG); #ifdef ENABLE_MEM_PROFILE + g_lock (mem_profile); freed_mem += *t; + g_unlock (mem_profile); #endif /* ENABLE_MEM_PROFILE */ mem = t; #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -321,8 +341,9 @@ g_realloc (gpointer mem, *t = size; #ifdef ENABLE_MEM_PROFILE + g_lock(mem_profile); #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS - if(!allocating_for_mem_chunk) { + if(!IS_IN_MEM_CHUNK_ROUTINE()) { #endif if (size <= (MEM_PROFILE_TABLE_SIZE - 1)) allocations[size-1] += 1; @@ -332,6 +353,7 @@ g_realloc (gpointer mem, #ifdef ENABLE_MEM_PROFILE_EXCLUDES_MEM_CHUNKS } #endif + g_unlock(mem_profile); #endif /* ENABLE_MEM_PROFILE */ #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -352,8 +374,10 @@ g_free (gpointer mem) #if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK) t = (gulong*) ((guchar*) mem - SIZEOF_LONG); size = *t; -#ifdef ENABLE_MEM_PROFILE +#ifdef ENABLE_MEM_PROFILE + g_lock (mem_profile); freed_mem += size; + g_unlock (mem_profile); #endif /* ENABLE_MEM_PROFILE */ mem = t; #endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */ @@ -380,19 +404,29 @@ g_mem_profile (void) { #ifdef ENABLE_MEM_PROFILE gint i; - + gulong local_allocations[MEM_PROFILE_TABLE_SIZE]; + gulong local_allocated_mem; + gulong local_freed_mem; + + g_lock (mem_profile); for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) - if (allocations[i] > 0) + local_allocations[i] = allocations[i]; + local_allocated_mem = allocated_mem; + local_freed_mem = freed_mem; + g_unlock (mem_profile); + + for (i = 0; i < (MEM_PROFILE_TABLE_SIZE - 1); i++) + if (local_allocations[i] > 0) g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, - "%lu allocations of %d bytes\n", allocations[i], i + 1); + "%lu allocations of %d bytes\n", local_allocations[i], i + 1); - if (allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0) + if (local_allocations[MEM_PROFILE_TABLE_SIZE - 1] > 0) g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu allocations of greater than %d bytes\n", - allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1); - g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", allocated_mem); - g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", freed_mem); - g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", allocated_mem - freed_mem); + local_allocations[MEM_PROFILE_TABLE_SIZE - 1], MEM_PROFILE_TABLE_SIZE - 1); + g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes allocated\n", local_allocated_mem); + g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes freed\n", local_freed_mem); + g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%lu bytes in use\n", local_allocated_mem - local_freed_mem); #endif /* ENABLE_MEM_PROFILE */ } @@ -460,11 +494,13 @@ g_mem_chunk_new (gchar *name, mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size); */ + g_lock (mem_chunks); mem_chunk->next = mem_chunks; mem_chunk->prev = NULL; if (mem_chunks) mem_chunks->prev = mem_chunk; mem_chunks = mem_chunk; + g_unlock (mem_chunks); LEAVE_MEM_CHUNK_ROUTINE(); @@ -497,8 +533,10 @@ g_mem_chunk_destroy (GMemChunk *mem_chunk) if (rmem_chunk->prev) rmem_chunk->prev->next = rmem_chunk->next; + g_lock (mem_chunks); if (rmem_chunk == mem_chunks) mem_chunks = mem_chunks->next; + g_unlock (mem_chunks); if (rmem_chunk->type == G_ALLOC_AND_FREE) g_tree_destroy (rmem_chunk->mem_tree); @@ -826,21 +864,26 @@ g_mem_chunk_info (void) gint count; count = 0; + g_lock (mem_chunks); mem_chunk = mem_chunks; while (mem_chunk) { count += 1; mem_chunk = mem_chunk->next; } + g_unlock (mem_chunks); g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "%d mem chunks\n", count); + g_lock (mem_chunks); mem_chunk = mem_chunks; + g_unlock (mem_chunks); + while (mem_chunk) { g_mem_chunk_print ((GMemChunk*) mem_chunk); mem_chunk = mem_chunk->next; - } + } } void @@ -848,7 +891,9 @@ g_blow_chunks (void) { GRealMemChunk *mem_chunk; + g_lock (mem_chunks); mem_chunk = mem_chunks; + g_unlock (mem_chunks); while (mem_chunk) { g_mem_chunk_clean ((GMemChunk*) mem_chunk); diff --git a/gmessages.c b/gmessages.c index 963dd921e..46e6d2f4f 100644 --- a/gmessages.c +++ b/gmessages.c @@ -72,7 +72,7 @@ struct _GLogHandler /* --- variables --- */ -static G_LOCK_DEFINE(gmessages_global); +static G_LOCK_DEFINE(g_messages_global); const gchar *g_log_domain_glib = "GLib"; static GLogDomain *g_log_domains = NULL; @@ -92,18 +92,18 @@ g_log_find_domain (const gchar *log_domain) { register GLogDomain *domain; - g_lock (gmessages_global); + g_lock (g_messages_global); domain = g_log_domains; while (domain) { if (strcmp (domain->log_domain, log_domain) == 0) { - g_unlock(gmessages_global); + g_unlock (g_messages_global); return domain; } domain = domain->next; } - g_unlock (gmessages_global); + g_unlock (g_messages_global); return NULL; } @@ -117,10 +117,10 @@ g_log_domain_new (const gchar *log_domain) domain->fatal_mask = G_LOG_FATAL_MASK; domain->handlers = NULL; - g_lock (gmessages_global); + g_lock (g_messages_global); domain->next = g_log_domains; g_log_domains = domain; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return domain; } @@ -135,7 +135,7 @@ g_log_domain_check_free (GLogDomain *domain) last = NULL; - g_lock (gmessages_global); + g_lock (g_messages_global); work = g_log_domains; while (work) { @@ -151,7 +151,7 @@ g_log_domain_check_free (GLogDomain *domain) } work = work->next; } - g_unlock (gmessages_global); + g_unlock (g_messages_global); } } @@ -190,10 +190,10 @@ g_log_set_always_fatal (GLogLevelFlags fatal_mask) /* remove bogus flag */ fatal_mask &= ~G_LOG_FLAG_FATAL; - g_lock (gmessages_global); + g_lock (g_messages_global); old_mask = g_log_always_fatal; g_log_always_fatal = fatal_mask; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_mask; } @@ -245,9 +245,9 @@ g_log_set_handler (const gchar *log_domain, domain = g_log_domain_new (log_domain); handler = g_new (GLogHandler, 1); - g_lock (gmessages_global); + g_lock (g_messages_global); handler->id = ++handler_id; - g_unlock (gmessages_global); + g_unlock (g_messages_global); handler->log_level = log_levels; handler->log_func = log_func; handler->data = user_data; @@ -348,11 +348,11 @@ g_logv (const gchar *log_domain, depth++; g_static_private_set (&g_log_depth, GUINT_TO_POINTER (depth), NULL); - g_lock (gmessages_global); + g_lock (g_messages_global); if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) | g_log_always_fatal) & test_level) != 0) test_level |= G_LOG_FLAG_FATAL; - g_unlock (gmessages_global); + g_unlock (g_messages_global); log_func = g_log_domain_get_handler (domain, test_level, &data); log_func (log_domain, test_level, buffer, data); @@ -414,11 +414,11 @@ g_log_default_handler (const gchar *log_domain, fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2; #endif - g_lock (gmessages_global); + g_lock (g_messages_global); local_glib_error_func = glib_error_func; local_glib_warning_func = glib_warning_func; local_glib_message_func = glib_message_func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); switch (log_level) { @@ -593,10 +593,10 @@ g_set_print_handler (GPrintFunc func) { GPrintFunc old_print_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_print_func = glib_print_func; glib_print_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_print_func; } @@ -615,9 +615,9 @@ g_print (const gchar *format, string = g_strdup_vprintf (format, args); va_end (args); - g_lock (gmessages_global); + g_lock (g_messages_global); local_glib_print_func = glib_print_func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); if (local_glib_print_func) local_glib_print_func (string); @@ -634,10 +634,10 @@ g_set_printerr_handler (GPrintFunc func) { GPrintFunc old_printerr_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_printerr_func = glib_printerr_func; glib_printerr_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_printerr_func; } @@ -656,9 +656,9 @@ g_printerr (const gchar *format, string = g_strdup_vprintf (format, args); va_end (args); - g_lock (gmessages_global); + g_lock (g_messages_global); local_glib_printerr_func = glib_printerr_func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); if (local_glib_printerr_func) local_glib_printerr_func (string); @@ -676,10 +676,10 @@ g_set_error_handler (GErrorFunc func) { GErrorFunc old_error_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_error_func = glib_error_func; glib_error_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_error_func; } @@ -690,10 +690,10 @@ g_set_warning_handler (GWarningFunc func) { GWarningFunc old_warning_func; - g_lock(gmessages_global); + g_lock (g_messages_global); old_warning_func = glib_warning_func; glib_warning_func = func; - g_unlock(gmessages_global); + g_unlock (g_messages_global); return old_warning_func; } @@ -704,10 +704,10 @@ g_set_message_handler (GPrintFunc func) { GPrintFunc old_message_func; - g_lock (gmessages_global); + g_lock (g_messages_global); old_message_func = glib_message_func; glib_message_func = func; - g_unlock (gmessages_global); + g_unlock (g_messages_global); return old_message_func; } diff --git a/gmutex.c b/gmutex.c index a26aa2a3a..0ba5a9a84 100644 --- a/gmutex.c +++ b/gmutex.c @@ -1,8 +1,9 @@ /* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * - * gmutex.c: + * gmutex.c: MT safety related functions * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * Owen Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public diff --git a/gnode.c b/gnode.c index b4d2de424..089a4996d 100644 --- a/gnode.c +++ b/gnode.c @@ -39,9 +39,10 @@ struct _GAllocator /* from gmem.c */ GNode *free_nodes; /* implementation specific */ }; -G_LOCK_DEFINE(current_allocator); +static G_LOCK_DEFINE(current_allocator); static GAllocator *current_allocator = NULL; +/* HOLDS: current_allocator_lock */ static void g_node_validate_allocator (GAllocator *allocator) { @@ -74,16 +75,16 @@ void g_node_push_allocator (GAllocator *allocator) { g_node_validate_allocator ( allocator ); - g_lock(current_allocator); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; - g_unlock(current_allocator); + g_unlock (current_allocator); } void g_node_pop_allocator (void) { - g_lock(current_allocator); + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -93,7 +94,7 @@ g_node_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } - g_unlock(current_allocator); + g_unlock (current_allocator); } @@ -103,12 +104,12 @@ g_node_new (gpointer data) { GNode *node; - g_lock(current_allocator); + g_lock (current_allocator); if (!current_allocator) { GAllocator *allocator = g_allocator_new ("GLib default GNode allocator", 1024); - g_node_validate_allocator ( allocator ); + g_node_validate_allocator (allocator); allocator->last = NULL; current_allocator = allocator; } @@ -119,7 +120,7 @@ g_node_new (gpointer data) node = current_allocator->free_nodes; current_allocator->free_nodes = node->next; } - g_unlock(current_allocator); + g_unlock (current_allocator); node->data = data; node->next = NULL; @@ -146,10 +147,10 @@ g_nodes_free (GNode *node) break; } - g_lock(current_allocator); + g_lock (current_allocator); parent->next = current_allocator->free_nodes; current_allocator->free_nodes = node; - g_unlock(current_allocator); + g_unlock (current_allocator); } void diff --git a/gslist.c b/gslist.c index b7ee371cc..1ed517ff6 100644 --- a/gslist.c +++ b/gslist.c @@ -38,6 +38,7 @@ struct _GAllocator /* from gmem.c */ static G_LOCK_DEFINE(current_allocator); static GAllocator *current_allocator = NULL; +/* HOLDS: current_allocator_lock */ static void g_slist_validate_allocator (GAllocator *allocator) { @@ -70,16 +71,16 @@ void g_slist_push_allocator (GAllocator *allocator) { g_slist_validate_allocator (allocator); - g_lock(current_allocator); + g_lock (current_allocator); allocator->last = current_allocator; current_allocator = allocator; - g_unlock(current_allocator); + g_unlock (current_allocator); } void g_slist_pop_allocator (void) { - g_lock(current_allocator); + g_lock (current_allocator); if (current_allocator) { GAllocator *allocator; @@ -89,7 +90,7 @@ g_slist_pop_allocator (void) allocator->last = NULL; allocator->is_unused = TRUE; } - g_unlock(current_allocator); + g_unlock (current_allocator); } GSList* @@ -97,12 +98,12 @@ g_slist_alloc (void) { GSList *list; - g_lock(current_allocator); + g_lock (current_allocator); if (!current_allocator) { GAllocator *allocator = g_allocator_new ("GLib default GSList allocator", 1024); - g_slist_validate_allocator ( allocator ); + g_slist_validate_allocator (allocator); allocator->last = NULL; current_allocator = allocator; } @@ -125,7 +126,7 @@ g_slist_alloc (void) current_allocator->free_lists = list->next; } } - g_unlock(current_allocator); + g_unlock (current_allocator); list->next = NULL; @@ -138,10 +139,10 @@ g_slist_free (GSList *list) if (list) { list->data = list->next; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } @@ -151,10 +152,10 @@ g_slist_free_1 (GSList *list) if (list) { list->data = NULL; - g_lock(current_allocator); + g_lock (current_allocator); list->next = current_allocator->free_lists; current_allocator->free_lists = list; - g_unlock(current_allocator); + g_unlock (current_allocator); } } diff --git a/gstrfuncs.c b/gstrfuncs.c index ad28978ee..e154c56dc 100644 --- a/gstrfuncs.c +++ b/gstrfuncs.c @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -208,7 +212,8 @@ g_strtod (const gchar *nptr, gchar* g_strerror (gint errnum) { - static char msg[64]; + static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; + char *msg; #ifdef HAVE_STRERROR return strerror (errnum); @@ -634,7 +639,14 @@ g_strerror (gint errnum) if ((errnum > 0) && (errnum <= sys_nerr)) return sys_errlist [errnum]; #endif /* NO_SYS_ERRLIST */ - + + msg = g_static_private_get (&msg_private); + if( !msg ) + { + msg = g_new( gchar, 64 ); + g_static_private_set (&msg_private, msg, g_free); + } + sprintf (msg, "unknown error (%d)", errnum); return msg; } @@ -642,7 +654,8 @@ g_strerror (gint errnum) gchar* g_strsignal (gint signum) { - static char msg[64]; + static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; + char *msg; #ifdef HAVE_STRSIGNAL extern char *strsignal (int sig); @@ -748,6 +761,13 @@ g_strsignal (gint signum) extern char *sys_siglist[]; return sys_siglist [signum]; #endif /* NO_SYS_SIGLIST */ + + msg = g_static_private_get (&msg_private); + if( !msg ) + { + msg = g_new( gchar, 64 ); + g_static_private_set (&msg_private, msg, g_free); + } sprintf (msg, "unknown signal (%d)", signum); return msg; diff --git a/gstring.c b/gstring.c index 3983cfc6b..312a54060 100644 --- a/gstring.c +++ b/gstring.c @@ -207,14 +207,14 @@ g_string_sized_new (guint dfl_size) { GRealString *string; - g_lock(string_mem_chunk); + g_lock (string_mem_chunk); if (!string_mem_chunk) string_mem_chunk = g_mem_chunk_new ("string mem chunk", sizeof (GRealString), 1024, G_ALLOC_AND_FREE); string = g_chunk_new (GRealString, string_mem_chunk); - g_unlock(string_mem_chunk); + g_unlock (string_mem_chunk); string->alloc = 0; string->len = 0; @@ -248,9 +248,9 @@ g_string_free (GString *string, if (free_segment) g_free (string->str); - g_unlock(string_mem_chunk); + g_lock (string_mem_chunk); g_mem_chunk_free (string_mem_chunk, string); - g_lock(string_mem_chunk); + g_unlock (string_mem_chunk); } GString* diff --git a/gthread/gthread-none.c b/gthread/gthread-none.c index 1197c97c7..1240fd580 100644 --- a/gthread/gthread-none.c +++ b/gthread/gthread-none.c @@ -1,2 +1,28 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: fallback thread system implementation + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + static GThreadFunctions g_mutex_functions_for_glib_use_default; /* is NULLified */ diff --git a/gthread/gthread-posix.c b/gthread/gthread-posix.c index ff494c8cb..d7cbe9884 100644 --- a/gthread/gthread-posix.c +++ b/gthread/gthread-posix.c @@ -1,3 +1,29 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: posix thread system implementation + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + #include #include #include @@ -36,7 +62,7 @@ g_mutex_free_posix_impl (GMutex* mutex) we might want to change this therfore. */ static gboolean -g_mutex_try_lock_posix_impl (GMutex* mutex) +g_mutex_trylock_posix_impl (GMutex* mutex) { int result; result = pthread_mutex_trylock((pthread_mutex_t*)mutex); @@ -136,7 +162,7 @@ static GThreadFunctions g_thread_functions_for_glib_use_default = { g_mutex_new_posix_impl, (void(*)(GMutex*))pthread_mutex_lock, - g_mutex_try_lock_posix_impl, + g_mutex_trylock_posix_impl, (void(*)(GMutex*))pthread_mutex_unlock, g_mutex_free_posix_impl, g_cond_new_posix_impl, diff --git a/gthread/gthread-solaris.c b/gthread/gthread-solaris.c index 5c4ced7ba..15d1baf61 100644 --- a/gthread/gthread-solaris.c +++ b/gthread/gthread-solaris.c @@ -1,56 +1,89 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: solaris thread system implementation + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + #include #include #include +#include -#define solaris_print_error( name, num ) \ - g_error( "file %s: line %d (%s): error %s during %s", \ - __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \ - g_strerror((num)), #name ) +/* we can't use g_log in the g_thread functions, because g_log depends + on these functions to work properly, we even should not use + g_strerror (might be a FIXME) */ -#define solaris_check_for_error( what ) G_STMT_START{ \ - int error = (what); \ - if( error ) { solaris_print_error( what, error ); } \ +#define solaris_error_args( name, num ) \ + "Gthread: Fatal error in file %s: line %d (%s): error %s during %s\n", \ + __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION, \ + g_strerror((num)), #name + +#define solaris_check_for_error( what ) G_STMT_START{ \ + int error = (what); \ + if( error ) { \ + fprintf(stderr, solaris_error_args( what, error ) ); \ + exit(1); \ + } \ }G_STMT_END -static GMutex* -g_mutex_new_solaris_impl() +static GMutex * +g_mutex_new_solaris_impl (void) { /* we can not use g_new and friends, as they might use mutexes by themself */ - GMutex* result = malloc(sizeof(mutex_t)); - solaris_check_for_error( mutex_init( (mutex_t*) result, USYNC_PROCESS, 0)); + GMutex *result = malloc (sizeof (mutex_t)); + solaris_check_for_error (result?NULL:ENOMEM); + solaris_check_for_error (mutex_init ((mutex_t *) result, USYNC_PROCESS, 0)); return result; } static void -g_mutex_free_solaris_impl(GMutex* mutex) +g_mutex_free_solaris_impl (GMutex * mutex) { - solaris_check_for_error( mutex_destroy((mutex_t*)mutex) ); - free (mutex); + solaris_check_for_error (mutex_destroy ((mutex_t *) mutex)); + free (mutex); } /* mutex_lock, mutex_unlock can be taken directly, as signature and semantic are right, but without error check then!!!!, - we might want to change this therfore. */ + we might want to change this therefore. */ static gboolean -g_mutex_try_lock_solaris_impl(GMutex* mutex) +g_mutex_trylock_solaris_impl (GMutex * mutex) { int result; - result = mutex_trylock((mutex_t*)mutex); - if( result == EBUSY ) - { - return FALSE; - } - solaris_check_for_error( result ); + result = mutex_trylock ((mutex_t *) mutex); + if (result == EBUSY) + return FALSE; + solaris_check_for_error (result); return TRUE; } -static GCond* -g_cond_new_solaris_impl() +static GCond * +g_cond_new_solaris_impl () { - GCond* result = (GCond*) g_new0 (cond_t, 1); - solaris_check_for_error( cond_init( (cond_t*)result, USYNC_THREAD, 0 ) ); + GCond *result = (GCond *) g_new0 (cond_t, 1); + solaris_check_for_error (cond_init ((cond_t *) result, USYNC_THREAD, 0)); return result; } @@ -62,83 +95,87 @@ g_cond_new_solaris_impl() #define G_MICROSEC 1000000 #define G_NANOSEC 1000000000 -static gboolean -g_cond_timed_wait_solaris_impl(GCond* cond, GMutex* entered_mutex, - GTimeVal *abs_time) +static gboolean +g_cond_timed_wait_solaris_impl (GCond * cond, GMutex * entered_mutex, + GTimeVal * abs_time) { int result; timestruc_t end_time; gboolean timed_out; - g_assert( cond ); - g_assert( entered_mutex ); + g_return_val_if_fail (cond != NULL, FALSE); + g_return_val_if_fail (entered_mutex != NULL, FALSE); - if( !abs_time ) + if (!abs_time) { - g_cond_wait(cond, entered_mutex); + g_cond_wait (cond, entered_mutex); return TRUE; } - + end_time.tv_sec = abs_time->tv_sec; - end_time.tv_nsec = abs_time->tv_usec * ( G_NANOSEC / G_MICROSEC ); - g_assert( end_time.tv_nsec < G_NANOSEC ); - result = cond_timedwait( (cond_t*)cond, (mutex_t*)entered_mutex, &end_time ); - timed_out = ( result == ETIME ); - if( !timed_out ) solaris_check_for_error( result ); + end_time.tv_nsec = abs_time->tv_usec * (G_NANOSEC / G_MICROSEC); + g_assert (end_time.tv_nsec < G_NANOSEC); + result = cond_timedwait ((cond_t *) cond, (mutex_t *) entered_mutex, + &end_time); + timed_out = (result == ETIME); + if (!timed_out) + solaris_check_for_error (result); return !timed_out; } -static void -g_cond_free_solaris_impl(GCond* cond) +static void +g_cond_free_solaris_impl (GCond * cond) { - solaris_check_for_error( cond_destroy((cond_t*)cond) ); - g_free (cond); + solaris_check_for_error (cond_destroy ((cond_t *) cond)); + g_free (cond); } -static GPrivate* -g_private_new_solaris_impl(GDestroyNotify destructor) +static GPrivate * +g_private_new_solaris_impl (GDestroyNotify destructor) { - /* we can not use g_new and friends, as they might use mutexes by - themself */ - GPrivate* result = malloc( sizeof(thread_key_t) ); - /* FIXME: we shouldn't use g_log here either actually */ - solaris_check_for_error( thr_keycreate( (thread_key_t*)result, destructor) ); + /* we can not use g_new and friends, as they might use private data + by themself */ + GPrivate *result = malloc (sizeof (thread_key_t)); + + solaris_check_for_error (malloc ? NULL : ENOMEM); + + solaris_check_for_error (thr_keycreate ((thread_key_t *) result, + destructor)); return result; } void -g_private_set_solaris_impl(GPrivate* private, gpointer value) +g_private_set_solaris_impl (GPrivate * private, gpointer value) { - g_assert( private ); + solaris_check_for_error (private ? NULL : EINVAL); - /* FIXME: we shouldn't use g_log here actually */ - solaris_check_for_error( thr_setspecific( *(thread_key_t*)private, value) ); + solaris_check_for_error (thr_setspecific (*(thread_key_t *) private, value)); } gpointer -g_private_get_solaris_impl(GPrivate* private) +g_private_get_solaris_impl (GPrivate * private) { gpointer result; - g_assert( private ); + solaris_check_for_error (private ? NULL : EINVAL); - /* FIXME: we shouldn't use g_log here actually */ - solaris_check_for_error( thr_getspecific( *(thread_key_t*)private, - &result) ); + solaris_check_for_error (thr_getspecific (*(thread_key_t *) private, + &result)); return result; } static GThreadFunctions -g_thread_functions_for_glib_use_default = { + g_thread_functions_for_glib_use_default = +{ g_mutex_new_solaris_impl, - (void(*)(GMutex*))mutex_lock, - g_mutex_try_lock_solaris_impl, - (void(*)(GMutex*))mutex_unlock, + (void (*)(GMutex *)) mutex_lock, + g_mutex_trylock_solaris_impl, + (void (*)(GMutex *)) mutex_unlock, g_mutex_free_solaris_impl, g_cond_new_solaris_impl, - (void(*)(GCond*))cond_signal, - (void(*)(GCond*))cond_broadcast, - (void(*)(GCond*,GMutex*))cond_wait, + (void (*)(GCond *)) cond_signal, + (void (*)(GCond *)) cond_broadcast, + (void (*)(GCond *, GMutex *)) cond_wait, g_cond_timed_wait_solaris_impl, g_cond_free_solaris_impl, g_private_new_solaris_impl, diff --git a/gthread/gthread.c b/gthread/gthread.c index a0733f9b6..5d8e60f99 100644 --- a/gthread/gthread.c +++ b/gthread/gthread.c @@ -1,3 +1,29 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: thread related functions + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -9,6 +35,8 @@ static gboolean thread_system_already_initialized = FALSE; #include G_THREAD_SOURCE +void g_mutex_init(); + gboolean g_thread_try_init(GThreadFunctions* init) { @@ -28,7 +56,7 @@ g_thread_try_init(GThreadFunctions* init) g_thread_supported = init->mutex_new && init->mutex_lock && - init->mutex_try_lock && + init->mutex_trylock && init->mutex_unlock && init->mutex_free && init->cond_new && @@ -41,12 +69,17 @@ g_thread_try_init(GThreadFunctions* init) init->private_get && init->private_get; - /* if somebody is calling g_thread_init(), it means that he at least wants - to have mutex support, so check this */ + /* if somebody is calling g_thread_init(), it means that he wants to + have thread support, so check this */ if (!g_thread_supported) g_error( "Mutex functions missing." ); + /* now call the thread initialization functions of the different + glib modules. BTW: order does matter, g_mutex_init MUST be first */ + + g_mutex_init(); + return TRUE; } diff --git a/gthread/testgthread.c b/gthread/testgthread.c index 19eeb5229..423763793 100644 --- a/gthread/testgthread.c +++ b/gthread/testgthread.c @@ -1,7 +1,12 @@ +#include + #define main testglib_main #include #undef main +#define TEST_PRIVATE_THREADS 9 +#define TEST_PRIVATE_ROUNDS 5 + void test_mutexes() { @@ -29,6 +34,97 @@ test_mutexes() g_mutex_free(mutex); } +#if defined(DEFAULTMUTEX) /* we are using solaris threads */ +gulong +new_thread(GHookFunc func, gpointer data) +{ + thread_t thread; + thr_create( NULL, 0, (void* (*)(void*))func, data, THR_BOUND, &thread); + return thread; +} +#define join_thread(thread) thr_join( (thread_t)thread, NULL, NULL ) +#define self_thread() (gulong)thr_self() +#elif defined(PTHREAD_MUTEX_INITIALIZER) /* we are using posix threads */ +gulong +new_thread(GHookFunc func, gpointer data) +{ + pthread_t thread; + pthread_attr_t pthread_attr; + pthread_attr_init( pthread_attr ); + pthread_attr_setdetachstate( pthread_attr, PTHREAD_CREATE_JOINABLE ); + pthread_create( &thread, &pthread_attr, (void* (*)(void*))func, data ); + return thread; +} +#define join_thread(thread) pthread_join( (pthread_t)thread, NULL ) +#define self_thread() (gulong)pthread_self() +#else /* we are not having a thread implementation, do nothing */ +#define new_thread(func,data) (0) +#define join_thread(thread) ((void)0) +#endif + +void +wait_thread(double seconds) +{ + GTimer *timer = g_timer_new(); + while( g_timer_elapsed (timer, NULL) < seconds ); +} + +gpointer +private_constructor() +{ + guint* result = g_new(guint,2); + result[0] = 0; + result[1] = self_thread(); + g_print("allocating data for the thread %d.\n",result[1]); + return result; +} + +void +private_destructor(gpointer data) +{ + guint* real = data; + g_print("freeing data for the thread %d.\n",real[1]); + g_free( real ); +} + +GStaticPrivate private; + +void +test_private_func(void* data) +{ + guint i = 0; + while( i < TEST_PRIVATE_ROUNDS ) + { + guint random_value = rand() % 10000; + guint* data = g_static_private_get( &private ); + if (!data) + { + data = private_constructor(); + g_static_private_set( &private, data, private_destructor ); + } + *data = random_value; + wait_thread(.2); + g_assert( *(guint*)g_static_private_get( &private ) == random_value ); + i++; + } +} + +void +test_private() +{ + int i; + gulong threads[ TEST_PRIVATE_THREADS ]; + for( i = 0; i < TEST_PRIVATE_THREADS; i++ ) + { + threads[ i ] = new_thread( test_private_func, (gpointer)i ); + } + for( i = 0; i < TEST_PRIVATE_THREADS; i++ ) + { + join_thread( threads[ i ] ); + } + g_print("\n"); +} + int main() { @@ -38,6 +134,8 @@ main() test_mutexes(); + test_private(); + /* later we might want to start n copies of that */ testglib_main(0,NULL); diff --git a/gtree.c b/gtree.c index b1167bc08..006f15db7 100644 --- a/gtree.c +++ b/gtree.c @@ -83,7 +83,7 @@ static GTreeNode* g_tree_node_rotate_right (GTreeNode *node); static void g_tree_node_check (GTreeNode *node); -static G_LOCK_DEFINE(gnode_global); +static G_LOCK_DEFINE(g_tree_global); static GMemChunk *node_mem_chunk = NULL; static GTreeNode *node_free_list = NULL; @@ -94,7 +94,7 @@ g_tree_node_new (gpointer key, { GTreeNode *node; - g_lock(gnode_global); + g_lock (g_tree_global); if (node_free_list) { node = node_free_list; @@ -110,7 +110,7 @@ g_tree_node_new (gpointer key, node = g_chunk_new (GTreeNode, node_mem_chunk); } - g_unlock(gnode_global); + g_unlock (g_tree_global); node->balance = 0; node->left = NULL; @@ -128,10 +128,10 @@ g_tree_node_destroy (GTreeNode *node) { g_tree_node_destroy (node->right); g_tree_node_destroy (node->left); - g_lock(gnode_global); + g_lock (g_tree_global); node->right = node_free_list; node_free_list = node; - g_unlock(gnode_global); + g_unlock (g_tree_global); } } @@ -385,10 +385,10 @@ g_tree_node_remove (GTreeNode *node, node = g_tree_node_restore_right_balance (new_root, old_balance); } - g_lock(gnode_global); + g_lock (g_tree_global); garbage->right = node_free_list; node_free_list = garbage; - g_unlock(gnode_global); + g_unlock (g_tree_global); } else if (cmp < 0) { diff --git a/gutils.c b/gutils.c index cc6594937..9a91199b6 100644 --- a/gutils.c +++ b/gutils.c @@ -17,6 +17,10 @@ * Boston, MA 02111-1307, USA. */ +/* + * MT safe for the unix part, FIXME: make the win32 part MT safe as well. + */ + #ifdef HAVE_CONFIG_H #include #endif @@ -367,11 +371,14 @@ g_getenv (const gchar *variable) #endif } +static G_LOCK_DEFINE(g_utils_global); + static gchar *g_tmp_dir = NULL; static gchar *g_user_name = NULL; static gchar *g_real_name = NULL; static gchar *g_home_dir = NULL; +/* HOLDS: g_utils_global_lock */ static void g_get_any_init (void) { @@ -442,14 +449,16 @@ g_get_any_init (void) g_home_dir = NULL; # endif /* !NATIVE_WIN32 */ #endif /* !HAVE_PWD_H */ - } + } } gchar* g_get_user_name (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); + g_unlock (g_utils_global); return g_user_name; } @@ -457,9 +466,11 @@ g_get_user_name (void) gchar* g_get_real_name (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); - + g_unlock (g_utils_global); + return g_real_name; } @@ -472,8 +483,10 @@ g_get_real_name (void) gchar* g_get_home_dir (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); + g_unlock (g_utils_global); return g_home_dir; } @@ -488,8 +501,10 @@ g_get_home_dir (void) gchar* g_get_tmp_dir (void) { + g_lock (g_utils_global); if (!g_tmp_dir) g_get_any_init (); + g_unlock (g_utils_global); return g_tmp_dir; } @@ -499,16 +514,25 @@ static gchar *g_prgname = NULL; gchar* g_get_prgname (void) { - return g_prgname; + gchar* retval; + + g_lock (g_utils_global); + retval = g_prgname; + g_unlock (g_utils_global); + + return retval; } void g_set_prgname (const gchar *prgname) { - gchar *c = g_prgname; - + gchar *c; + + g_lock (g_utils_global); + c = g_prgname; g_prgname = g_strdup (prgname); g_free (c); + g_unlock (g_utils_global); } guint