moved G_DATALIST_*_POINTER() macros here, because proper use requires the

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.
This commit is contained in:
Tim Janik 2005-07-31 00:05:39 +00:00 committed by Tim Janik
parent 4746cf2ce0
commit 2d1cf6c139
6 changed files with 76 additions and 23 deletions

View 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

View 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

View 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

View 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

View 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"
@ -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 */

View File

@ -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