Introduce virHashAtomic

This is a self-locking wrapper around virHashTable. Only a limited set
of APIs are implemented now (the ones which are used in the following
patch) as more can be added on demand.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Jiri Denemark 2015-07-02 14:21:27 +02:00
parent 1cd70869d9
commit a7c22a1f29
3 changed files with 94 additions and 0 deletions

View File

@ -1476,6 +1476,9 @@ virFirewallStartTransaction;
# util/virhash.h
virHashAddEntry;
virHashAtomicNew;
virHashAtomicSteal;
virHashAtomicUpdate;
virHashCreate;
virHashEqual;
virHashForEach;

View File

@ -31,6 +31,7 @@
#include "virhashcode.h"
#include "virrandom.h"
#include "virstring.h"
#include "virobject.h"
#define VIR_FROM_THIS VIR_FROM_NONE
@ -76,6 +77,28 @@ struct _virHashTable {
virHashKeyFree keyFree;
};
struct _virHashAtomic {
virObjectLockable parent;
virHashTablePtr hash;
};
static virClassPtr virHashAtomicClass;
static void virHashAtomicDispose(void *obj);
static int virHashAtomicOnceInit(void)
{
virHashAtomicClass = virClassNew(virClassForObjectLockable(),
"virHashAtomic",
sizeof(virHashAtomic),
virHashAtomicDispose);
if (!virHashAtomicClass)
return -1;
else
return 0;
}
VIR_ONCE_GLOBAL_INIT(virHashAtomic)
static uint32_t virHashStrCode(const void *name, uint32_t seed)
{
return virHashCodeGen(name, strlen(name), seed);
@ -178,6 +201,36 @@ virHashTablePtr virHashCreate(ssize_t size, virHashDataFree dataFree)
virHashStrFree);
}
virHashAtomicPtr
virHashAtomicNew(ssize_t size,
virHashDataFree dataFree)
{
virHashAtomicPtr hash;
if (virHashAtomicInitialize() < 0)
return NULL;
if (!(hash = virObjectLockableNew(virHashAtomicClass)))
return NULL;
if (!(hash->hash = virHashCreate(size, dataFree))) {
virObjectUnref(hash);
return NULL;
}
return hash;
}
static void
virHashAtomicDispose(void *obj)
{
virHashAtomicPtr hash = obj;
virHashFree(hash->hash);
}
/**
* virHashGrow:
* @table: the hash table
@ -360,6 +413,21 @@ virHashUpdateEntry(virHashTablePtr table, const void *name,
return virHashAddOrUpdateEntry(table, name, userdata, true);
}
int
virHashAtomicUpdate(virHashAtomicPtr table,
const void *name,
void *userdata)
{
int ret;
virObjectLock(table);
ret = virHashAddOrUpdateEntry(table->hash, name, userdata, true);
virObjectUnlock(table);
return ret;
}
/**
* virHashLookup:
* @table: the hash table
@ -409,6 +477,19 @@ void *virHashSteal(virHashTablePtr table, const void *name)
return data;
}
void *
virHashAtomicSteal(virHashAtomicPtr table,
const void *name)
{
void *data;
virObjectLock(table);
data = virHashSteal(table->hash, name);
virObjectUnlock(table);
return data;
}
/**
* virHashSize:

View File

@ -21,6 +21,9 @@
typedef struct _virHashTable virHashTable;
typedef virHashTable *virHashTablePtr;
typedef struct _virHashAtomic virHashAtomic;
typedef virHashAtomic *virHashAtomicPtr;
/*
* function types:
*/
@ -101,6 +104,8 @@ typedef void (*virHashKeyFree)(void *name);
*/
virHashTablePtr virHashCreate(ssize_t size,
virHashDataFree dataFree);
virHashAtomicPtr virHashAtomicNew(ssize_t size,
virHashDataFree dataFree);
virHashTablePtr virHashCreateFull(ssize_t size,
virHashDataFree dataFree,
virHashKeyCode keyCode,
@ -119,6 +124,9 @@ int virHashAddEntry(virHashTablePtr table,
int virHashUpdateEntry(virHashTablePtr table,
const void *name,
void *userdata);
int virHashAtomicUpdate(virHashAtomicPtr table,
const void *name,
void *userdata);
/*
* Remove an entry from the hash table.
@ -140,6 +148,8 @@ void *virHashLookup(const virHashTable *table, const void *name);
* Retrieve & remove the userdata.
*/
void *virHashSteal(virHashTablePtr table, const void *name);
void *virHashAtomicSteal(virHashAtomicPtr table,
const void *name);
/*
* Get the hash table's key/value pairs and have them optionally sorted.