moved G_DATALIST_*_POINTER() macros here, because proper use requires the
authorTim Janik <timj@gtk.org>
Sun, 31 Jul 2005 00:05:39 +0000 (00:05 +0000)
committerTim Janik <timj@src.gnome.org>
Sun, 31 Jul 2005 00:05:39 +0000 (00:05 +0000)
Sun Jul 31 01:50:20 2005  Tim Janik  <timj@gtk.org>

        * 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
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-8
glib/gdataset.c
glib/gdatasetprivate.h

index 3ef50b1..691ea63 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Sun Jul 31 01:50:20 2005  Tim Janik  <timj@gtk.org>
+
+       * 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  <mclasen@redhat.com>
 
        * glib/goption.c: Include glibintl.h, not gi18n.h, noticed
index 3ef50b1..691ea63 100644 (file)
@@ -1,3 +1,15 @@
+Sun Jul 31 01:50:20 2005  Tim Janik  <timj@gtk.org>
+
+       * 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  <mclasen@redhat.com>
 
        * glib/goption.c: Include glibintl.h, not gi18n.h, noticed
index 3ef50b1..691ea63 100644 (file)
@@ -1,3 +1,15 @@
+Sun Jul 31 01:50:20 2005  Tim Janik  <timj@gtk.org>
+
+       * 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  <mclasen@redhat.com>
 
        * glib/goption.c: Include glibintl.h, not gi18n.h, noticed
index 3ef50b1..691ea63 100644 (file)
@@ -1,3 +1,15 @@
+Sun Jul 31 01:50:20 2005  Tim Janik  <timj@gtk.org>
+
+       * 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  <mclasen@redhat.com>
 
        * glib/goption.c: Include glibintl.h, not gi18n.h, noticed
index 43580e4..ff9bca7 100644 (file)
@@ -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"
 #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 */
index 1a2e319..1a0d947 100644 (file)
 
 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
-
-#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
+  ((gsize) g_atomic_pointer_get (datalist) & G_DATALIST_FLAGS_MASK)
+
 
 G_END_DECLS