tag: lock all accesses to tag_pool

The tag pool is a shared global resource that is infrequently
modified.  However, it can occasionally be modified by several
threads, especially by the metadata_pipe for streaming metadata
(both reading/writing).

The bulk tag_item pool is NOT locked as currently only the
update thread uses it.
This commit is contained in:
Eric Wong 2008-09-07 19:14:45 +02:00 committed by Max Kellermann
parent 194c8c3c0f
commit 3c4de5b560
3 changed files with 15 additions and 6 deletions

View File

@ -244,8 +244,9 @@ static void deleteItem(struct tag *tag, int idx)
assert(idx < tag->numOfItems); assert(idx < tag->numOfItems);
tag->numOfItems--; tag->numOfItems--;
pthread_mutex_lock(&tag_pool_lock);
tag_pool_put_item(tag->items[idx]); tag_pool_put_item(tag->items[idx]);
/* free(tag->items[idx].value); */ pthread_mutex_unlock(&tag_pool_lock);
if (tag->numOfItems - idx > 0) { if (tag->numOfItems - idx > 0) {
memmove(tag->items + idx, tag->items + idx + 1, memmove(tag->items + idx, tag->items + idx + 1,
@ -277,10 +278,10 @@ static void clearMpdTag(struct tag *tag)
{ {
int i; int i;
for (i = 0; i < tag->numOfItems; i++) { pthread_mutex_lock(&tag_pool_lock);
/* free(tag->items[i].value); */ for (i = 0; i < tag->numOfItems; i++)
tag_pool_put_item(tag->items[i]); tag_pool_put_item(tag->items[i]);
} pthread_mutex_unlock(&tag_pool_lock);
if (tag->items == bulk.items) { if (tag->items == bulk.items) {
#ifndef NDEBUG #ifndef NDEBUG
@ -317,9 +318,10 @@ struct tag *tag_dup(const struct tag *tag)
ret->numOfItems = tag->numOfItems; ret->numOfItems = tag->numOfItems;
ret->items = ret->numOfItems > 0 ? xmalloc(items_size(tag)) : NULL; ret->items = ret->numOfItems > 0 ? xmalloc(items_size(tag)) : NULL;
for (i = 0; i < tag->numOfItems; i++) { pthread_mutex_lock(&tag_pool_lock);
for (i = 0; i < tag->numOfItems; i++)
ret->items[i] = tag_pool_dup_item(tag->items[i]); ret->items[i] = tag_pool_dup_item(tag->items[i]);
} pthread_mutex_unlock(&tag_pool_lock);
return ret; return ret;
} }
@ -428,7 +430,9 @@ static void appendToTagItems(struct tag *tag, enum tag_type type,
items_size(tag) - sizeof(struct tag_item)); items_size(tag) - sizeof(struct tag_item));
} }
pthread_mutex_lock(&tag_pool_lock);
tag->items[i] = tag_pool_get_item(type, p, len); tag->items[i] = tag_pool_get_item(type, p, len);
pthread_mutex_unlock(&tag_pool_lock);
if (p != value) if (p != value)
xfree(p); xfree(p);

View File

@ -19,6 +19,8 @@
#include "tag_pool.h" #include "tag_pool.h"
#include "utils.h" #include "utils.h"
pthread_mutex_t tag_pool_lock = PTHREAD_MUTEX_INITIALIZER;
#define NUM_SLOTS 4096 #define NUM_SLOTS 4096
struct slot { struct slot {

View File

@ -20,6 +20,9 @@
#define TAG_POOL_H #define TAG_POOL_H
#include "tag.h" #include "tag.h"
#include "os_compat.h"
extern pthread_mutex_t tag_pool_lock;
struct tag_item; struct tag_item;