1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-13 08:58:33 +03:00

util: hash: Use virHashForEachSafe in places which might delete the element

Convert all calls to virHashForEach where it's not obvious that the
callback is _not_ deleting the current element from the hash to
virHashForEachSafe which will be deemed safe to do such operation.

Now that no iterator used with virHashForEach deletes current element we
can document that virHashForEach must not touch the hash table in any
way.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Matt Coleman <matt@datto.com>
This commit is contained in:
Peter Krempa 2020-10-23 09:49:36 +02:00
parent 80f3af5fd8
commit 247460ab41
8 changed files with 12 additions and 10 deletions

View File

@ -299,7 +299,7 @@ void virChrdevFree(virChrdevsPtr devs)
return; return;
virMutexLock(&devs->lock); virMutexLock(&devs->lock);
virHashForEach(devs->hash, virChrdevFreeClearCallbacks, NULL); virHashForEachSafe(devs->hash, virChrdevFreeClearCallbacks, NULL);
virHashFree(devs->hash); virHashFree(devs->hash);
virMutexUnlock(&devs->lock); virMutexUnlock(&devs->lock);
virMutexDestroy(&devs->lock); virMutexDestroy(&devs->lock);

View File

@ -475,7 +475,7 @@ virDomainMomentForEach(virDomainMomentObjListPtr moments,
virHashIterator iter, virHashIterator iter,
void *data) void *data)
{ {
return virHashForEach(moments->objs, iter, data); return virHashForEachSafe(moments->objs, iter, data);
} }

View File

@ -837,7 +837,7 @@ virDomainObjListForEach(virDomainObjListPtr doms,
virObjectRWLockWrite(doms); virObjectRWLockWrite(doms);
else else
virObjectRWLockRead(doms); virObjectRWLockRead(doms);
virHashForEach(doms->objs, virDomainObjListHelper, &data); virHashForEachSafe(doms->objs, virDomainObjListHelper, &data);
virObjectRWUnlock(doms); virObjectRWUnlock(doms);
return data.ret; return data.ret;
} }

View File

@ -1468,7 +1468,7 @@ virNetworkObjListForEach(virNetworkObjListPtr nets,
struct virNetworkObjListForEachHelperData data = { struct virNetworkObjListForEachHelperData data = {
.callback = callback, .opaque = opaque, .ret = 0}; .callback = callback, .opaque = opaque, .ret = 0};
virObjectRWLockRead(nets); virObjectRWLockRead(nets);
virHashForEach(nets->objs, virNetworkObjListForEachHelper, &data); virHashForEachSafe(nets->objs, virNetworkObjListForEachHelper, &data);
virObjectRWUnlock(nets); virObjectRWUnlock(nets);
return data.ret; return data.ret;
} }
@ -1841,7 +1841,7 @@ virNetworkObjPortForEach(virNetworkObjPtr obj,
void *opaque) void *opaque)
{ {
virNetworkObjPortListForEachData data = { iter, opaque, false }; virNetworkObjPortListForEachData data = { iter, opaque, false };
virHashForEach(obj->ports, virNetworkObjPortForEachCallback, &data); virHashForEachSafe(obj->ports, virNetworkObjPortForEachCallback, &data);
if (data.err) if (data.err)
return -1; return -1;
return 0; return 0;

View File

@ -364,7 +364,7 @@ virNWFilterBindingObjListForEach(virNWFilterBindingObjListPtr bindings,
callback, opaque, 0, callback, opaque, 0,
}; };
virObjectRWLockRead(bindings); virObjectRWLockRead(bindings);
virHashForEach(bindings->objs, virNWFilterBindingObjListHelper, &data); virHashForEachSafe(bindings->objs, virNWFilterBindingObjListHelper, &data);
virObjectRWUnlock(bindings); virObjectRWUnlock(bindings);
return data.ret; return data.ret;
} }

View File

@ -465,7 +465,7 @@ virStoragePoolObjListForEach(virStoragePoolObjListPtr pools,
struct _virStoragePoolObjListForEachData data = { .iter = iter, struct _virStoragePoolObjListForEachData data = { .iter = iter,
.opaque = opaque }; .opaque = opaque };
virHashForEach(pools->objs, virStoragePoolObjListForEachCb, &data); virHashForEachSafe(pools->objs, virStoragePoolObjListForEachCb, &data);
} }
@ -753,7 +753,7 @@ virStoragePoolObjForEachVolume(virStoragePoolObjPtr obj,
.iter = iter, .opaque = opaque }; .iter = iter, .opaque = opaque };
virObjectRWLockRead(obj->volumes); virObjectRWLockRead(obj->volumes);
virHashForEach(obj->volumes->objsKey, virStoragePoolObjForEachVolumeCb, virHashForEachSafe(obj->volumes->objsKey, virStoragePoolObjForEachVolumeCb,
&data); &data);
virObjectRWUnlock(obj->volumes); virObjectRWUnlock(obj->volumes);
return 0; return 0;

View File

@ -490,7 +490,9 @@ virHashRemoveEntry(virHashTablePtr table, const char *name)
* *
* The elements are iterated in arbitrary order. * The elements are iterated in arbitrary order.
* *
* virHashForEach, virHashForEachSafe allow the callback to remove the current * virHashForEach prohibits @iter from modifying @table
*
* virHashForEachSafe allows the callback to remove the current
* element using virHashRemoveEntry but calling other virHash* functions is * element using virHashRemoveEntry but calling other virHash* functions is
* prohibited. Note that removing the entry invalidates @key and @payload in * prohibited. Note that removing the entry invalidates @key and @payload in
* the callback. * the callback.

View File

@ -218,7 +218,7 @@ testHashRemoveForEach(const void *data)
if (!(hash = testHashInit())) if (!(hash = testHashInit()))
return -1; return -1;
if (virHashForEach(hash, (virHashIterator) info->data, hash)) { if (virHashForEachSafe(hash, (virHashIterator) info->data, hash)) {
VIR_TEST_VERBOSE("\nvirHashForEach didn't go through all entries"); VIR_TEST_VERBOSE("\nvirHashForEach didn't go through all entries");
goto cleanup; goto cleanup;
} }