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 # util/virhash.h
virHashAddEntry; virHashAddEntry;
virHashAtomicNew;
virHashAtomicSteal;
virHashAtomicUpdate;
virHashCreate; virHashCreate;
virHashEqual; virHashEqual;
virHashForEach; virHashForEach;

View File

@ -31,6 +31,7 @@
#include "virhashcode.h" #include "virhashcode.h"
#include "virrandom.h" #include "virrandom.h"
#include "virstring.h" #include "virstring.h"
#include "virobject.h"
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
@ -76,6 +77,28 @@ struct _virHashTable {
virHashKeyFree keyFree; 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) static uint32_t virHashStrCode(const void *name, uint32_t seed)
{ {
return virHashCodeGen(name, strlen(name), seed); return virHashCodeGen(name, strlen(name), seed);
@ -178,6 +201,36 @@ virHashTablePtr virHashCreate(ssize_t size, virHashDataFree dataFree)
virHashStrFree); 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: * virHashGrow:
* @table: the hash table * @table: the hash table
@ -360,6 +413,21 @@ virHashUpdateEntry(virHashTablePtr table, const void *name,
return virHashAddOrUpdateEntry(table, name, userdata, true); 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: * virHashLookup:
* @table: the hash table * @table: the hash table
@ -409,6 +477,19 @@ void *virHashSteal(virHashTablePtr table, const void *name)
return data; return data;
} }
void *
virHashAtomicSteal(virHashAtomicPtr table,
const void *name)
{
void *data;
virObjectLock(table);
data = virHashSteal(table->hash, name);
virObjectUnlock(table);
return data;
}
/** /**
* virHashSize: * virHashSize:

View File

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