mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
util: Introduce and use virObjectRWLockWrite
Instead of making virObjectLock be the entry point for two different types of locks, let's create a virObjectRWLockWrite API which will only handle the virObjectRWLockableClass objects. Use the new virObjectRWLockWrite for the virdomainobjlist code in order to handle the Add, Remove, Rename, and Load operations that need to be very synchronous. Signed-off-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
99a72b3eb4
commit
908b33644e
@ -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;
|
||||
|
@ -2312,6 +2312,7 @@ virObjectNew;
|
||||
virObjectRef;
|
||||
virObjectRWLockableNew;
|
||||
virObjectRWLockRead;
|
||||
virObjectRWLockWrite;
|
||||
virObjectUnlock;
|
||||
virObjectUnref;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user