aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-09-05 00:10:48 -0700
committerEric Wong <normalperson@yhbt.net>2008-09-05 00:27:01 -0700
commitf0a68935f9da6a77cd4688fc5836b2ce8f058041 (patch)
tree3380fd00129c615b0efb6c591b2ee043c8a582f1
parent6e8200227f617b7604a01f372460661d8ec5da32 (diff)
downloadmpd-f0a68935f9da6a77cd4688fc5836b2ce8f058041.tar.gz
mpd-f0a68935f9da6a77cd4688fc5836b2ce8f058041.tar.xz
mpd-f0a68935f9da6a77cd4688fc5836b2ce8f058041.zip
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.
-rw-r--r--src/tag.c16
-rw-r--r--src/tag_pool.c2
-rw-r--r--src/tag_pool.h3
3 files changed, 15 insertions, 6 deletions
diff --git a/src/tag.c b/src/tag.c
index dc2bab2d6..8208eb965 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -267,8 +267,9 @@ static void deleteItem(struct mpd_tag *tag, int idx)
assert(idx < tag->numOfItems);
tag->numOfItems--;
+ pthread_mutex_lock(&tag_pool_lock);
tag_pool_put_item(tag->items[idx]);
- /* free(tag->items[idx].value); */
+ pthread_mutex_unlock(&tag_pool_lock);
if (tag->numOfItems - idx > 0) {
memmove(tag->items + idx, tag->items + idx + 1,
@@ -300,10 +301,10 @@ static void clearMpdTag(struct mpd_tag *tag)
{
int i;
- for (i = 0; i < tag->numOfItems; i++) {
- /* free(tag->items[i].value); */
+ pthread_mutex_lock(&tag_pool_lock);
+ for (i = 0; i < tag->numOfItems; i++)
tag_pool_put_item(tag->items[i]);
- }
+ pthread_mutex_unlock(&tag_pool_lock);
if (tag->items == bulk.items) {
#ifndef NDEBUG
@@ -340,9 +341,10 @@ struct mpd_tag *tag_dup(const struct mpd_tag *tag)
ret->numOfItems = tag->numOfItems;
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]);
- }
+ pthread_mutex_unlock(&tag_pool_lock);
return ret;
}
@@ -451,7 +453,9 @@ static void appendToTagItems(struct mpd_tag *tag, enum tag_type type,
items_size(tag) - sizeof(struct tag_item));
}
+ pthread_mutex_lock(&tag_pool_lock);
tag->items[i] = tag_pool_get_item(type, p, len);
+ pthread_mutex_unlock(&tag_pool_lock);
if (p != value)
free(deconst_ptr(p));
diff --git a/src/tag_pool.c b/src/tag_pool.c
index 89efef1fc..d227a2988 100644
--- a/src/tag_pool.c
+++ b/src/tag_pool.c
@@ -19,6 +19,8 @@
#include "tag_pool.h"
#include "utils.h"
+pthread_mutex_t tag_pool_lock = PTHREAD_MUTEX_INITIALIZER;
+
#define NUM_SLOTS 4096
struct slot {
diff --git a/src/tag_pool.h b/src/tag_pool.h
index e19b2f4b4..d837d4446 100644
--- a/src/tag_pool.h
+++ b/src/tag_pool.h
@@ -20,6 +20,9 @@
#define TAG_POOL_H
#include "tag.h"
+#include "os_compat.h"
+
+extern pthread_mutex_t tag_pool_lock;
struct tag_item;