Mercurial > audlegacy
changeset 3427:7c2e63c5a001 trunk
Add a global GStaticRWLock to Tuple handling code. This should prevent
some concurrent access cases, but not _all_ of them.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 07 Sep 2007 06:25:02 +0300 |
parents | 50a88dd6b992 |
children | 268847521d6f |
files | src/audacious/tuple.c |
diffstat | 1 files changed, 63 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/audacious/tuple.c Tue Sep 04 23:47:01 2007 +0200 +++ b/src/audacious/tuple.c Fri Sep 07 06:25:02 2007 +0300 @@ -27,6 +27,13 @@ static mowgli_heap_t *tuple_value_heap = NULL; static mowgli_object_class_t tuple_klass; +static GStaticRWLock tuple_rwlock = G_STATIC_RW_LOCK_INIT; + +#define TUPLE_LOCK_WRITE(XX) g_static_rw_lock_writer_lock(&tuple_rwlock) +#define TUPLE_UNLOCK_WRITE(XX) g_static_rw_lock_writer_unlock(&tuple_rwlock) +#define TUPLE_LOCK_READ(XX) g_static_rw_lock_reader_lock(&tuple_rwlock) +#define TUPLE_UNLOCK_READ(XX) g_static_rw_lock_reader_unlock(&tuple_rwlock) + /* iterative destructor of tuple values. */ static void tuple_value_destroy(mowgli_dictionary_elem_t *delem, gpointer privdata) @@ -44,8 +51,10 @@ { Tuple *tuple = (Tuple *) data; + TUPLE_LOCK_WRITE(); mowgli_dictionary_destroy(tuple->dict, tuple_value_destroy, NULL); mowgli_heap_free(tuple_heap, tuple); + TUPLE_UNLOCK_WRITE(); } Tuple * @@ -53,6 +62,8 @@ { Tuple *tuple; + TUPLE_LOCK_WRITE(); + if (tuple_heap == NULL) { tuple_heap = mowgli_heap_create(sizeof(Tuple), 256, BH_NOW); @@ -67,6 +78,8 @@ tuple->dict = mowgli_dictionary_create(g_ascii_strcasecmp); + TUPLE_UNLOCK_WRITE(); + return tuple; } @@ -111,18 +124,22 @@ g_return_val_if_fail(tuple != NULL, FALSE); g_return_val_if_fail(field != NULL, FALSE); + TUPLE_LOCK_WRITE(); if ((value = mowgli_dictionary_delete(tuple->dict, field))) tuple_disassociate_now(value); - - if (string == NULL) + + if (string == NULL) { + TUPLE_UNLOCK_WRITE(); return TRUE; + } value = mowgli_heap_alloc(tuple_value_heap); value->type = TUPLE_STRING; value->value.string = g_strdup(string); mowgli_dictionary_add(tuple->dict, field, value); - + TUPLE_UNLOCK_WRITE(); + return TRUE; } @@ -134,6 +151,7 @@ g_return_val_if_fail(tuple != NULL, FALSE); g_return_val_if_fail(field != NULL, FALSE); + TUPLE_LOCK_WRITE(); if ((value = mowgli_dictionary_delete(tuple->dict, field))) tuple_disassociate_now(value); @@ -142,7 +160,8 @@ value->value.integer = integer; mowgli_dictionary_add(tuple->dict, field, value); - + TUPLE_UNLOCK_WRITE(); + return TRUE; } @@ -164,10 +183,16 @@ g_return_if_fail(field != NULL); /* why _delete()? because _delete() returns the dictnode's data on success */ - if ((value = mowgli_dictionary_delete(tuple->dict, field)) == NULL) + TUPLE_LOCK_WRITE(); + value = mowgli_dictionary_delete(tuple->dict, field); + + if (value == NULL) { + TUPLE_UNLOCK_WRITE(); return; + } tuple_disassociate_now(value); + TUPLE_UNLOCK_WRITE(); } TupleValueType @@ -178,7 +203,11 @@ g_return_val_if_fail(tuple != NULL, TUPLE_UNKNOWN); g_return_val_if_fail(field != NULL, TUPLE_UNKNOWN); - if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) == NULL) + TUPLE_LOCK_READ(); + value = mowgli_dictionary_retrieve(tuple->dict, field); + TUPLE_UNLOCK_READ(); + + if (value == NULL) return TUPLE_UNKNOWN; return value->type; @@ -188,32 +217,54 @@ tuple_get_string(Tuple *tuple, const gchar *field) { TupleValue *value; + gchar *val; g_return_val_if_fail(tuple != NULL, NULL); g_return_val_if_fail(field != NULL, NULL); - if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) == NULL) + TUPLE_LOCK_READ(); + value = mowgli_dictionary_retrieve(tuple->dict, field); + + if (value == NULL) { + TUPLE_UNLOCK_READ(); return NULL; + } - if (value->type != TUPLE_STRING) + if (value->type != TUPLE_STRING) { + TUPLE_UNLOCK_READ(); mowgli_throw_exception_val(audacious.tuple.invalid_type_request, NULL); + } - return value->value.string; + val = value->value.string; + TUPLE_UNLOCK_READ(); + + return val; } int tuple_get_int(Tuple *tuple, const gchar *field) { TupleValue *value; + gint val; g_return_val_if_fail(tuple != NULL, 0); g_return_val_if_fail(field != NULL, 0); - if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) == NULL) + TUPLE_LOCK_READ(); + value = mowgli_dictionary_retrieve(tuple->dict, field); + + if (value == NULL) { + TUPLE_UNLOCK_READ(); return 0; + } - if (value->type != TUPLE_INT) + if (value->type != TUPLE_INT) { + TUPLE_UNLOCK_READ(); mowgli_throw_exception_val(audacious.tuple.invalid_type_request, 0); + } - return value->value.integer; + val = value->value.integer; + TUPLE_UNLOCK_READ(); + + return val; }