diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c index 9bc6603353..573032f14b 100644 --- a/src/conf/virdomainobjlist.c +++ b/src/conf/virdomainobjlist.c @@ -327,7 +327,7 @@ virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr doms, { virDomainObjPtr ret; - virObjectLock(doms); + virObjectRWLockWrite(doms); ret = virDomainObjListAddLocked(doms, def, xmlopt, flags, oldDef); virObjectUnlock(doms); return ret; @@ -349,7 +349,7 @@ void virDomainObjListRemove(virDomainObjListPtr doms, virObjectRef(dom); virObjectUnlock(dom); - virObjectLock(doms); + virObjectRWLockWrite(doms); virObjectLock(dom); virHashRemoveEntry(doms->objs, uuidstr); virHashRemoveEntry(doms->objsName, dom->def->name); @@ -394,7 +394,7 @@ virDomainObjListRename(virDomainObjListPtr doms, * hold a lock on dom but not refcount it. */ virObjectRef(dom); virObjectUnlock(dom); - virObjectLock(doms); + virObjectRWLockWrite(doms); virObjectLock(dom); virObjectUnref(dom); @@ -573,7 +573,7 @@ virDomainObjListLoadAllConfigs(virDomainObjListPtr doms, if ((rc = virDirOpenIfExists(&dir, configDir)) <= 0) return rc; - virObjectLock(doms); + virObjectRWLockWrite(doms); while ((ret = virDirRead(dir, &entry, configDir)) > 0) { virDomainObjPtr dom; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b5fc31a64f..01a2f3a814 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2312,6 +2312,7 @@ virObjectNew; virObjectRef; virObjectRWLockableNew; virObjectRWLockRead; +virObjectRWLockWrite; virObjectUnlock; virObjectUnref; diff --git a/src/util/virobject.c b/src/util/virobject.c index b97f251afd..f49af62c81 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -429,12 +429,43 @@ virObjectRWLockRead(void *anyobj) } +/** + * virObjectRWLockWrite: + * @anyobj: any instance of virObjectRWLockable + * + * Acquire a write lock on @anyobj. The lock must be + * released by virObjectUnlock. + * + * The caller is expected to have acquired a reference + * on the object before locking it (eg virObjectRef). + * The object must be unlocked before releasing this + * reference. + * + * NB: It's possible to return without the lock if + * @anyobj was invalid - this has been considered + * a programming error rather than something that + * should be checked. + */ +void +virObjectRWLockWrite(void *anyobj) +{ + if (virObjectIsClass(anyobj, virObjectRWLockableClass)) { + virObjectRWLockablePtr obj = anyobj; + virRWLockWrite(&obj->lock); + } else { + virObjectPtr obj = anyobj; + VIR_WARN("Object %p (%s) is not a virObjectRWLockable instance", + anyobj, obj ? obj->klass->name : "(unknown)"); + } +} + + /** * virObjectUnlock: * @anyobj: any instance of virObjectLockable or virObjectRWLockable * * Release a lock on @anyobj. The lock must have been acquired by - * virObjectLock or virObjectRWLockRead. + * virObjectLock, virObjectRWLockRead, or virObjectRWLockWrite. */ void virObjectUnlock(void *anyobj) diff --git a/src/util/virobject.h b/src/util/virobject.h index e7ca983921..24ee6dda8b 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -128,6 +128,10 @@ void virObjectRWLockRead(void *lockableobj) ATTRIBUTE_NONNULL(1); +void +virObjectRWLockWrite(void *lockableobj) + ATTRIBUTE_NONNULL(1); + void virObjectUnlock(void *lockableobj) ATTRIBUTE_NONNULL(1);