From 2d1cf6c139f06d964f5fcddaac126370fdf59215 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Sun, 31 Jul 2005 00:05:39 +0000 Subject: [PATCH] moved G_DATALIST_*_POINTER() macros here, because proper use requires the Sun Jul 31 01:50:20 2005 Tim Janik * glib/gdataset.c: moved G_DATALIST_*_POINTER() macros here, because proper use requires the global g_dataset_global mutex to be acquired. g_datalist_id_get_data(): g_datalist_unset_flags(): g_datalist_set_flags(): properly acquire and release dataset mutex. * glib/gdatasetprivate.h: implement G_DATALIST_GET_FLAGS() via atomic pointer access to account for memory barriers. moved all other macros. --- ChangeLog | 12 ++++++++++++ ChangeLog.pre-2-10 | 12 ++++++++++++ ChangeLog.pre-2-12 | 12 ++++++++++++ ChangeLog.pre-2-8 | 12 ++++++++++++ glib/gdataset.c | 34 ++++++++++++++++++++++++---------- glib/gdatasetprivate.h | 17 ++++------------- 6 files changed, 76 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ef50b120..691ea63ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Sun Jul 31 01:50:20 2005 Tim Janik + + * glib/gdataset.c: + moved G_DATALIST_*_POINTER() macros here, because proper use requires + the global g_dataset_global mutex to be acquired. + g_datalist_id_get_data(): + g_datalist_unset_flags(): + g_datalist_set_flags(): properly acquire and release dataset mutex. + + * glib/gdatasetprivate.h: implement G_DATALIST_GET_FLAGS() via atomic + pointer access to account for memory barriers. moved all other macros. + 2005-07-26 Matthias Clasen * glib/goption.c: Include glibintl.h, not gi18n.h, noticed diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 3ef50b120..691ea63ba 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,15 @@ +Sun Jul 31 01:50:20 2005 Tim Janik + + * glib/gdataset.c: + moved G_DATALIST_*_POINTER() macros here, because proper use requires + the global g_dataset_global mutex to be acquired. + g_datalist_id_get_data(): + g_datalist_unset_flags(): + g_datalist_set_flags(): properly acquire and release dataset mutex. + + * glib/gdatasetprivate.h: implement G_DATALIST_GET_FLAGS() via atomic + pointer access to account for memory barriers. moved all other macros. + 2005-07-26 Matthias Clasen * glib/goption.c: Include glibintl.h, not gi18n.h, noticed diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 3ef50b120..691ea63ba 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,15 @@ +Sun Jul 31 01:50:20 2005 Tim Janik + + * glib/gdataset.c: + moved G_DATALIST_*_POINTER() macros here, because proper use requires + the global g_dataset_global mutex to be acquired. + g_datalist_id_get_data(): + g_datalist_unset_flags(): + g_datalist_set_flags(): properly acquire and release dataset mutex. + + * glib/gdatasetprivate.h: implement G_DATALIST_GET_FLAGS() via atomic + pointer access to account for memory barriers. moved all other macros. + 2005-07-26 Matthias Clasen * glib/goption.c: Include glibintl.h, not gi18n.h, noticed diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 3ef50b120..691ea63ba 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,15 @@ +Sun Jul 31 01:50:20 2005 Tim Janik + + * glib/gdataset.c: + moved G_DATALIST_*_POINTER() macros here, because proper use requires + the global g_dataset_global mutex to be acquired. + g_datalist_id_get_data(): + g_datalist_unset_flags(): + g_datalist_set_flags(): properly acquire and release dataset mutex. + + * glib/gdatasetprivate.h: implement G_DATALIST_GET_FLAGS() via atomic + pointer access to account for memory barriers. moved all other macros. + 2005-07-26 Matthias Clasen * glib/goption.c: Include glibintl.h, not gi18n.h, noticed diff --git a/glib/gdataset.c b/glib/gdataset.c index 43580e46a..ff9bca721 100644 --- a/glib/gdataset.c +++ b/glib/gdataset.c @@ -27,8 +27,7 @@ */ /* - * MT safe ; FIXME: might still freeze, watch out, not thoroughly - * looked at yet. + * MT safe ; except for g_data*_foreach() */ #include "config.h" @@ -46,6 +45,14 @@ #define G_DATA_CACHE_MAX (512) #define G_DATASET_MEM_CHUNK_PREALLOC (32) +/* datalist pointer modifications have to be done with the g_dataset_global mutex held */ +#define G_DATALIST_GET_POINTER(datalist) \ + ((GData*) ((gsize) *(datalist) & ~(gsize) G_DATALIST_FLAGS_MASK)) +#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \ + *(datalist) = (GData*) (G_DATALIST_GET_FLAGS (datalist) | \ + (gsize) pointer); \ +} G_STMT_END + /* --- structures --- */ typedef struct _GDataset GDataset; @@ -453,18 +460,21 @@ gpointer g_datalist_id_get_data (GData **datalist, GQuark key_id) { + gpointer data = NULL; g_return_val_if_fail (datalist != NULL, NULL); - if (key_id) { register GData *list; - + G_LOCK (g_dataset_global); for (list = G_DATALIST_GET_POINTER (datalist); list; list = list->next) if (list->id == key_id) - return list->data; + { + data = list->data; + break; + } + G_UNLOCK (g_dataset_global); } - - return NULL; + return data; } void @@ -547,7 +557,9 @@ g_datalist_set_flags (GData **datalist, g_return_if_fail (datalist != NULL); g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); - G_DATALIST_SET_FLAGS (datalist, flags); + G_LOCK (g_dataset_global); + *datalist = (GData*) (flags | (gsize) *datalist); + G_UNLOCK (g_dataset_global); } /** @@ -568,7 +580,9 @@ g_datalist_unset_flags (GData **datalist, g_return_if_fail (datalist != NULL); g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); - G_DATALIST_UNSET_FLAGS (datalist, flags); + G_LOCK (g_dataset_global); + *datalist = (GData*) (~(gsize) flags & (gsize) *datalist); + G_UNLOCK (g_dataset_global); } /** @@ -585,7 +599,7 @@ g_datalist_get_flags (GData **datalist) { g_return_val_if_fail (datalist != NULL, 0); - return G_DATALIST_GET_FLAGS (datalist); + return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */ } /* HOLDS: g_dataset_global_lock */ diff --git a/glib/gdatasetprivate.h b/glib/gdatasetprivate.h index 1a2e3197a..1a0d947ff 100644 --- a/glib/gdatasetprivate.h +++ b/glib/gdatasetprivate.h @@ -32,21 +32,12 @@ G_BEGIN_DECLS +/* GET_FLAGS is implemented via atomic pointer access, to allow memory + * barriers take effect without acquirering the global dataset mutex. + */ #define G_DATALIST_GET_FLAGS(datalist) \ - ((gsize)*(datalist) & G_DATALIST_FLAGS_MASK) -#define G_DATALIST_SET_FLAGS(datalist, flags) G_STMT_START { \ - *datalist = (GData *)((flags) | (gsize)*(datalist)); \ -} G_STMT_END -#define G_DATALIST_UNSET_FLAGS(datalist, flags) G_STMT_START { \ - *datalist = (GData *)(~(gsize)(flags) & (gsize)*(datalist)); \ -} G_STMT_END + ((gsize) g_atomic_pointer_get (datalist) & G_DATALIST_FLAGS_MASK) -#define G_DATALIST_GET_POINTER(datalist) \ - ((GData *)((gsize)*(datalist) & ~(gsize)G_DATALIST_FLAGS_MASK)) -#define G_DATALIST_SET_POINTER(datalist,pointer) G_STMT_START { \ - *(datalist) = (GData *)(G_DATALIST_GET_FLAGS (datalist) | \ - (gsize)pointer); \ -} G_STMT_END G_END_DECLS