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:
parent
194c8c3c0f
commit
3c4de5b560
16
src/tag.c
16
src/tag.c
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user