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;
 }