Mercurial > audlegacy
comparison src/audacious/tuple.c @ 3430:91c27073aa13 trunk
Automated merge with ssh://hg.atheme.org//hg/audacious
| author | William Pitcock <nenolod@atheme.org> |
|---|---|
| date | Fri, 07 Sep 2007 00:18:50 -0500 |
| parents | 7c2e63c5a001 |
| children | 004f822505b0 890326d0898b |
comparison
equal
deleted
inserted
replaced
| 3429:05b732174e5f | 3430:91c27073aa13 |
|---|---|
| 25 | 25 |
| 26 static mowgli_heap_t *tuple_heap = NULL; | 26 static mowgli_heap_t *tuple_heap = NULL; |
| 27 static mowgli_heap_t *tuple_value_heap = NULL; | 27 static mowgli_heap_t *tuple_value_heap = NULL; |
| 28 static mowgli_object_class_t tuple_klass; | 28 static mowgli_object_class_t tuple_klass; |
| 29 | 29 |
| 30 static GStaticRWLock tuple_rwlock = G_STATIC_RW_LOCK_INIT; | |
| 31 | |
| 32 #define TUPLE_LOCK_WRITE(XX) g_static_rw_lock_writer_lock(&tuple_rwlock) | |
| 33 #define TUPLE_UNLOCK_WRITE(XX) g_static_rw_lock_writer_unlock(&tuple_rwlock) | |
| 34 #define TUPLE_LOCK_READ(XX) g_static_rw_lock_reader_lock(&tuple_rwlock) | |
| 35 #define TUPLE_UNLOCK_READ(XX) g_static_rw_lock_reader_unlock(&tuple_rwlock) | |
| 36 | |
| 30 /* iterative destructor of tuple values. */ | 37 /* iterative destructor of tuple values. */ |
| 31 static void | 38 static void |
| 32 tuple_value_destroy(mowgli_dictionary_elem_t *delem, gpointer privdata) | 39 tuple_value_destroy(mowgli_dictionary_elem_t *delem, gpointer privdata) |
| 33 { | 40 { |
| 34 TupleValue *value = (TupleValue *) delem->data; | 41 TupleValue *value = (TupleValue *) delem->data; |
| 42 static void | 49 static void |
| 43 tuple_destroy(gpointer data) | 50 tuple_destroy(gpointer data) |
| 44 { | 51 { |
| 45 Tuple *tuple = (Tuple *) data; | 52 Tuple *tuple = (Tuple *) data; |
| 46 | 53 |
| 54 TUPLE_LOCK_WRITE(); | |
| 47 mowgli_dictionary_destroy(tuple->dict, tuple_value_destroy, NULL); | 55 mowgli_dictionary_destroy(tuple->dict, tuple_value_destroy, NULL); |
| 48 mowgli_heap_free(tuple_heap, tuple); | 56 mowgli_heap_free(tuple_heap, tuple); |
| 57 TUPLE_UNLOCK_WRITE(); | |
| 49 } | 58 } |
| 50 | 59 |
| 51 Tuple * | 60 Tuple * |
| 52 tuple_new(void) | 61 tuple_new(void) |
| 53 { | 62 { |
| 54 Tuple *tuple; | 63 Tuple *tuple; |
| 55 | 64 |
| 65 TUPLE_LOCK_WRITE(); | |
| 66 | |
| 56 if (tuple_heap == NULL) | 67 if (tuple_heap == NULL) |
| 57 { | 68 { |
| 58 tuple_heap = mowgli_heap_create(sizeof(Tuple), 256, BH_NOW); | 69 tuple_heap = mowgli_heap_create(sizeof(Tuple), 256, BH_NOW); |
| 59 tuple_value_heap = mowgli_heap_create(sizeof(TupleValue), 512, BH_NOW); | 70 tuple_value_heap = mowgli_heap_create(sizeof(TupleValue), 512, BH_NOW); |
| 60 mowgli_object_class_init(&tuple_klass, "audacious.tuple", tuple_destroy, FALSE); | 71 mowgli_object_class_init(&tuple_klass, "audacious.tuple", tuple_destroy, FALSE); |
| 65 tuple = mowgli_heap_alloc(tuple_heap); | 76 tuple = mowgli_heap_alloc(tuple_heap); |
| 66 mowgli_object_init(mowgli_object(tuple), NULL, &tuple_klass, NULL); | 77 mowgli_object_init(mowgli_object(tuple), NULL, &tuple_klass, NULL); |
| 67 | 78 |
| 68 tuple->dict = mowgli_dictionary_create(g_ascii_strcasecmp); | 79 tuple->dict = mowgli_dictionary_create(g_ascii_strcasecmp); |
| 69 | 80 |
| 81 TUPLE_UNLOCK_WRITE(); | |
| 82 | |
| 70 return tuple; | 83 return tuple; |
| 71 } | 84 } |
| 72 | 85 |
| 73 Tuple * | 86 Tuple * |
| 74 tuple_new_from_filename(const gchar *filename) | 87 tuple_new_from_filename(const gchar *filename) |
| 109 TupleValue *value; | 122 TupleValue *value; |
| 110 | 123 |
| 111 g_return_val_if_fail(tuple != NULL, FALSE); | 124 g_return_val_if_fail(tuple != NULL, FALSE); |
| 112 g_return_val_if_fail(field != NULL, FALSE); | 125 g_return_val_if_fail(field != NULL, FALSE); |
| 113 | 126 |
| 127 TUPLE_LOCK_WRITE(); | |
| 114 if ((value = mowgli_dictionary_delete(tuple->dict, field))) | 128 if ((value = mowgli_dictionary_delete(tuple->dict, field))) |
| 115 tuple_disassociate_now(value); | 129 tuple_disassociate_now(value); |
| 116 | 130 |
| 117 if (string == NULL) | 131 if (string == NULL) { |
| 132 TUPLE_UNLOCK_WRITE(); | |
| 118 return TRUE; | 133 return TRUE; |
| 134 } | |
| 119 | 135 |
| 120 value = mowgli_heap_alloc(tuple_value_heap); | 136 value = mowgli_heap_alloc(tuple_value_heap); |
| 121 value->type = TUPLE_STRING; | 137 value->type = TUPLE_STRING; |
| 122 value->value.string = g_strdup(string); | 138 value->value.string = g_strdup(string); |
| 123 | 139 |
| 124 mowgli_dictionary_add(tuple->dict, field, value); | 140 mowgli_dictionary_add(tuple->dict, field, value); |
| 125 | 141 TUPLE_UNLOCK_WRITE(); |
| 142 | |
| 126 return TRUE; | 143 return TRUE; |
| 127 } | 144 } |
| 128 | 145 |
| 129 gboolean | 146 gboolean |
| 130 tuple_associate_int(Tuple *tuple, const gchar *field, gint integer) | 147 tuple_associate_int(Tuple *tuple, const gchar *field, gint integer) |
| 132 TupleValue *value; | 149 TupleValue *value; |
| 133 | 150 |
| 134 g_return_val_if_fail(tuple != NULL, FALSE); | 151 g_return_val_if_fail(tuple != NULL, FALSE); |
| 135 g_return_val_if_fail(field != NULL, FALSE); | 152 g_return_val_if_fail(field != NULL, FALSE); |
| 136 | 153 |
| 154 TUPLE_LOCK_WRITE(); | |
| 137 if ((value = mowgli_dictionary_delete(tuple->dict, field))) | 155 if ((value = mowgli_dictionary_delete(tuple->dict, field))) |
| 138 tuple_disassociate_now(value); | 156 tuple_disassociate_now(value); |
| 139 | 157 |
| 140 value = mowgli_heap_alloc(tuple_value_heap); | 158 value = mowgli_heap_alloc(tuple_value_heap); |
| 141 value->type = TUPLE_INT; | 159 value->type = TUPLE_INT; |
| 142 value->value.integer = integer; | 160 value->value.integer = integer; |
| 143 | 161 |
| 144 mowgli_dictionary_add(tuple->dict, field, value); | 162 mowgli_dictionary_add(tuple->dict, field, value); |
| 145 | 163 TUPLE_UNLOCK_WRITE(); |
| 164 | |
| 146 return TRUE; | 165 return TRUE; |
| 147 } | 166 } |
| 148 | 167 |
| 149 void | 168 void |
| 150 tuple_disassociate_now(TupleValue *value) | 169 tuple_disassociate_now(TupleValue *value) |
| 162 | 181 |
| 163 g_return_if_fail(tuple != NULL); | 182 g_return_if_fail(tuple != NULL); |
| 164 g_return_if_fail(field != NULL); | 183 g_return_if_fail(field != NULL); |
| 165 | 184 |
| 166 /* why _delete()? because _delete() returns the dictnode's data on success */ | 185 /* why _delete()? because _delete() returns the dictnode's data on success */ |
| 167 if ((value = mowgli_dictionary_delete(tuple->dict, field)) == NULL) | 186 TUPLE_LOCK_WRITE(); |
| 187 value = mowgli_dictionary_delete(tuple->dict, field); | |
| 188 | |
| 189 if (value == NULL) { | |
| 190 TUPLE_UNLOCK_WRITE(); | |
| 168 return; | 191 return; |
| 192 } | |
| 169 | 193 |
| 170 tuple_disassociate_now(value); | 194 tuple_disassociate_now(value); |
| 195 TUPLE_UNLOCK_WRITE(); | |
| 171 } | 196 } |
| 172 | 197 |
| 173 TupleValueType | 198 TupleValueType |
| 174 tuple_get_value_type(Tuple *tuple, const gchar *field) | 199 tuple_get_value_type(Tuple *tuple, const gchar *field) |
| 175 { | 200 { |
| 176 TupleValue *value; | 201 TupleValue *value; |
| 177 | 202 |
| 178 g_return_val_if_fail(tuple != NULL, TUPLE_UNKNOWN); | 203 g_return_val_if_fail(tuple != NULL, TUPLE_UNKNOWN); |
| 179 g_return_val_if_fail(field != NULL, TUPLE_UNKNOWN); | 204 g_return_val_if_fail(field != NULL, TUPLE_UNKNOWN); |
| 180 | 205 |
| 181 if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) == NULL) | 206 TUPLE_LOCK_READ(); |
| 207 value = mowgli_dictionary_retrieve(tuple->dict, field); | |
| 208 TUPLE_UNLOCK_READ(); | |
| 209 | |
| 210 if (value == NULL) | |
| 182 return TUPLE_UNKNOWN; | 211 return TUPLE_UNKNOWN; |
| 183 | 212 |
| 184 return value->type; | 213 return value->type; |
| 185 } | 214 } |
| 186 | 215 |
| 187 const gchar * | 216 const gchar * |
| 188 tuple_get_string(Tuple *tuple, const gchar *field) | 217 tuple_get_string(Tuple *tuple, const gchar *field) |
| 189 { | 218 { |
| 190 TupleValue *value; | 219 TupleValue *value; |
| 220 gchar *val; | |
| 191 | 221 |
| 192 g_return_val_if_fail(tuple != NULL, NULL); | 222 g_return_val_if_fail(tuple != NULL, NULL); |
| 193 g_return_val_if_fail(field != NULL, NULL); | 223 g_return_val_if_fail(field != NULL, NULL); |
| 194 | 224 |
| 195 if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) == NULL) | 225 TUPLE_LOCK_READ(); |
| 226 value = mowgli_dictionary_retrieve(tuple->dict, field); | |
| 227 | |
| 228 if (value == NULL) { | |
| 229 TUPLE_UNLOCK_READ(); | |
| 196 return NULL; | 230 return NULL; |
| 197 | 231 } |
| 198 if (value->type != TUPLE_STRING) | 232 |
| 233 if (value->type != TUPLE_STRING) { | |
| 234 TUPLE_UNLOCK_READ(); | |
| 199 mowgli_throw_exception_val(audacious.tuple.invalid_type_request, NULL); | 235 mowgli_throw_exception_val(audacious.tuple.invalid_type_request, NULL); |
| 200 | 236 } |
| 201 return value->value.string; | 237 |
| 238 val = value->value.string; | |
| 239 TUPLE_UNLOCK_READ(); | |
| 240 | |
| 241 return val; | |
| 202 } | 242 } |
| 203 | 243 |
| 204 int | 244 int |
| 205 tuple_get_int(Tuple *tuple, const gchar *field) | 245 tuple_get_int(Tuple *tuple, const gchar *field) |
| 206 { | 246 { |
| 207 TupleValue *value; | 247 TupleValue *value; |
| 248 gint val; | |
| 208 | 249 |
| 209 g_return_val_if_fail(tuple != NULL, 0); | 250 g_return_val_if_fail(tuple != NULL, 0); |
| 210 g_return_val_if_fail(field != NULL, 0); | 251 g_return_val_if_fail(field != NULL, 0); |
| 211 | 252 |
| 212 if ((value = mowgli_dictionary_retrieve(tuple->dict, field)) == NULL) | 253 TUPLE_LOCK_READ(); |
| 254 value = mowgli_dictionary_retrieve(tuple->dict, field); | |
| 255 | |
| 256 if (value == NULL) { | |
| 257 TUPLE_UNLOCK_READ(); | |
| 213 return 0; | 258 return 0; |
| 214 | 259 } |
| 215 if (value->type != TUPLE_INT) | 260 |
| 261 if (value->type != TUPLE_INT) { | |
| 262 TUPLE_UNLOCK_READ(); | |
| 216 mowgli_throw_exception_val(audacious.tuple.invalid_type_request, 0); | 263 mowgli_throw_exception_val(audacious.tuple.invalid_type_request, 0); |
| 217 | 264 } |
| 218 return value->value.integer; | 265 |
| 219 } | 266 val = value->value.integer; |
| 267 TUPLE_UNLOCK_READ(); | |
| 268 | |
| 269 return val; | |
| 270 } |
