Current processing requires a "fire dance" unlocking the @obj, adding an @obj ref, locking the @interfaces, and relocking @obj in order to ensure proper lock ordering. This can be avoided by changing virInterfaceObjListRemove to take @name instead of @obj. Then, we can lock the @interfaces list, look up the @obj by @name (like we do when adding), and remove the @obj from the list. This removes the last reference to the object effectively reaping it. NB: Since prior to calling we remove the reference to the object we cannot pass anything contained within the object (such as the obj->def or obj->def->name) because it's possible that the object could be reaped by two competing remove threads. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/conf/virinterfaceobj.c | 26 +++++++++++++++++--------- src/conf/virinterfaceobj.h | 2 +- src/test/test_driver.c | 4 ++-- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c index f90c0bd9c..c3a7d4cd8 100644 --- a/src/conf/virinterfaceobj.c +++ b/src/conf/virinterfaceobj.c @@ -358,20 +358,28 @@ virInterfaceObjListAssignDef(virInterfaceObjListPtr interfaces, } +/* + * virInterfaceObjListRemove: + * @interfaces: list of interface objects + * @name: name of interface definition to remove + * + * Find the object by name in the list, remove the object from the + * list hash table, and free the object. + * + * Upon entry it's expected that prior to entry any locks on + * the object related to @name will have been removed. + */ void virInterfaceObjListRemove(virInterfaceObjListPtr interfaces, - virInterfaceObjPtr obj) + const char *name) { - if (!obj) - return; + virInterfaceObjPtr obj; - virObjectRef(obj); - virObjectUnlock(obj); virObjectRWLockWrite(interfaces); - virObjectLock(obj); - virHashRemoveEntry(interfaces->objsName, obj->def->name); - virObjectUnlock(obj); - virObjectUnref(obj); + if ((obj = virInterfaceObjListFindByNameLocked(interfaces, name))) { + virHashRemoveEntry(interfaces->objsName, name); + virInterfaceObjEndAPI(&obj); + } virObjectRWUnlock(interfaces); } diff --git a/src/conf/virinterfaceobj.h b/src/conf/virinterfaceobj.h index 799d38038..82eb2ee87 100644 --- a/src/conf/virinterfaceobj.h +++ b/src/conf/virinterfaceobj.h @@ -66,7 +66,7 @@ virInterfaceObjListAssignDef(virInterfaceObjListPtr interfaces, void virInterfaceObjListRemove(virInterfaceObjListPtr interfaces, - virInterfaceObjPtr obj); + const char *name); typedef bool (*virInterfaceObjListFilter)(virConnectPtr conn, diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 99c27cc0a..ddddd8dcb 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -4092,8 +4092,8 @@ testInterfaceUndefine(virInterfacePtr iface) if (!(obj = testInterfaceObjFindByName(privconn, iface->name))) return -1; - virInterfaceObjListRemove(privconn->ifaces, obj); - virObjectUnref(obj); + virInterfaceObjEndAPI(&obj); + virInterfaceObjListRemove(privconn->ifaces, iface->name); return 0; } -- 2.13.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list