Add a pair of API's to add/remove the LookupKeys object to/from the
LookupHash object. The caller must check return status and handle
failure properly for the Add. The Remove API callers are all void
functions, so only report the problem and ignore the attempt to
remove if for some reason the passed @tableobj is not as expected.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/libvirt_private.syms | 2 ++
src/util/virobject.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virobject.h | 10 ++++++
3 files changed, 104 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9eb0589..c6d22d7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2331,7 +2331,9 @@ virObjectListFree;
virObjectListFreeCount;
virObjectLock;
virObjectLockableNew;
+virObjectLookupHashAdd;
virObjectLookupHashNew;
+virObjectLookupHashRemove;
virObjectLookupKeysIsActive;
virObjectLookupKeysNew;
virObjectLookupKeysSetActive;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 657597f..59c8ac6 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -858,3 +858,95 @@ virObjectLookupKeysSetActive(void *anyobj,
obj->active = active;
}
+
+
+static virObjectLookupHashPtr
+virObjectGetLookupHashObj(void *anyobj)
+{
+ if (virObjectIsClass(anyobj, virObjectLookupHashClass))
+ return anyobj;
+
+ VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, virObjectLookupHashClass);
+
+ return NULL;
+}
+
+
+/**
+ * virObjectLookupHashAdd:
+ * @anyobj: LookupHash object
+ * @obj: The LookupKeys object to insert in the hash table(s)
+ *
+ * Insert @obj into the hash tables found in @anyobj. Assumes that the
+ * caller has determined that the key1 and possibly key2 do not already
+ * exist in their respective hash table to be inserted.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int
+virObjectLookupHashAdd(void *anyobj,
+ virObjectLookupKeysPtr obj)
+{
+ virObjectLookupHashPtr hashObj = virObjectGetLookupHashObj(anyobj);
+
+ if (!hashObj)
+ return -1;
+
+ if (obj->key2 && !hashObj->objsKey2) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("hashObj=%p has one table, but two keys from
obj=%p"),
+ hashObj, obj);
+ return -1;
+ }
+
+ if (virHashAddEntry(hashObj->objsKey1, obj->key1, obj) < 0)
+ return -1;
+ virObjectRef(obj);
+
+ if (obj->key2) {
+ if (virHashAddEntry(hashObj->objsKey2, obj->key2, obj) < 0) {
+ virHashRemoveEntry(hashObj->objsKey1, obj->key1);
+ return -1;
+ }
+ virObjectRef(obj);
+ }
+
+ return 0;
+}
+
+
+/**
+ * virObjectLookupHashRemove:
+ * @anyobj: LookupHash object
+ * @obj: The LookupKeys object to remove from the hash table(s)
+ *
+ * Remove @obj from the hash tables found in @anyobj. The common
+ * function to remove an object from a hash table will also cause
+ * the virObjectUnref to be called via virObjectFreeHashData since
+ * the virHashCreate used that as the Free object element argument.
+ *
+ * Even though this is a void, report the error for a bad @anyobj.
+ */
+void
+virObjectLookupHashRemove(void *anyobj,
+ virObjectLookupKeysPtr obj)
+{
+ virObjectLookupHashPtr hashObj;
+
+ if (!obj)
+ return;
+
+ if (!(hashObj = virObjectGetLookupHashObj(anyobj)))
+ return;
+
+ virObjectRef(obj);
+ virObjectUnlock(obj);
+ virObjectRWLockWrite(hashObj);
+ virObjectLock(obj);
+ virHashRemoveEntry(hashObj->objsKey1, obj->key1);
+ if (obj->key2)
+ virHashRemoveEntry(hashObj->objsKey2, obj->key2);
+ virObjectUnlock(obj);
+ virObjectUnref(obj);
+ virObjectRWUnlock(hashObj);
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 0d3b90b..bb02781 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -199,4 +199,14 @@ virObjectLookupKeysSetActive(void *anyobj,
bool active)
ATTRIBUTE_NONNULL(1);
+int
+virObjectLookupHashAdd(void *anyobj,
+ virObjectLookupKeysPtr obj)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+void
+virObjectLookupHashRemove(void *anyobj,
+ virObjectLookupKeysPtr obj)
+ ATTRIBUTE_NONNULL(1);
+
#endif /* __VIR_OBJECT_H */
--
2.9.4