From b7d4c300c3b046d48743116a3ed01c91f0019160 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 18 Mar 2010 14:20:53 +0000 Subject: [PATCH] Add new internal domain events APIs for handling other event types The current internal domain events API tracks callbacks based on the function pointer, and only supports lifecycle events. This adds new internal APIs for registering callbacks for other event types. These new APIs are postfixed with the word 'ID' to indicate that they operated based on event ID, instead of hardcoded to lifecycle events * src/conf/domain_event.c, src/conf/domain_event.h, src/libvirt_private.syms: Add new APIs for handling callbacks for non-lifecycle events --- src/conf/domain_event.c | 169 ++++++++++++++++++++++++++++++++++++--- src/conf/domain_event.h | 28 ++++++- src/libvirt_private.syms | 6 ++ 3 files changed, 190 insertions(+), 13 deletions(-) diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index a44ab3de1..d73933211 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -136,6 +136,51 @@ virDomainEventCallbackListRemove(virConnectPtr conn, } +/** + * virDomainEventCallbackListRemoveID: + * @conn: pointer to the connection + * @cbList: the list + * @callback: the callback to remove + * + * Internal function to remove a callback from a virDomainEventCallbackListPtr + */ +int +virDomainEventCallbackListRemoveID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int callbackID) +{ + int i; + for (i = 0 ; i < cbList->count ; i++) { + if (cbList->callbacks[i]->callbackID == callbackID && + cbList->callbacks[i]->conn == conn) { + virFreeCallback freecb = cbList->callbacks[i]->freecb; + if (freecb) + (*freecb)(cbList->callbacks[i]->opaque); + virUnrefConnect(cbList->callbacks[i]->conn); + VIR_FREE(cbList->callbacks[i]); + + if (i < (cbList->count - 1)) + memmove(cbList->callbacks + i, + cbList->callbacks + i + 1, + sizeof(*(cbList->callbacks)) * + (cbList->count - (i + 1))); + + if (VIR_REALLOC_N(cbList->callbacks, + cbList->count - 1) < 0) { + ; /* Failure to reduce memory allocation isn't fatal */ + } + cbList->count--; + + return 0; + } + } + + eventReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("could not find event callback for removal")); + return -1; +} + + /** * virDomainEventCallbackListRemoveConn: * @conn: pointer to the connection @@ -195,6 +240,25 @@ int virDomainEventCallbackListMarkDelete(virConnectPtr conn, } +int virDomainEventCallbackListMarkDeleteID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int callbackID) +{ + int i; + for (i = 0 ; i < cbList->count ; i++) { + if (cbList->callbacks[i]->callbackID == callbackID && + cbList->callbacks[i]->conn == conn) { + cbList->callbacks[i]->deleted = 1; + return 0; + } + } + + eventReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("could not find event callback for deletion")); + return -1; +} + + int virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList) { int old_count = cbList->count; @@ -239,6 +303,32 @@ virDomainEventCallbackListAdd(virConnectPtr conn, virConnectDomainEventCallback callback, void *opaque, virFreeCallback freecb) +{ + return virDomainEventCallbackListAddID(conn, cbList, NULL, + VIR_DOMAIN_EVENT_ID_LIFECYCLE, + VIR_DOMAIN_EVENT_CALLBACK(callback), + opaque, freecb); +} + + +/** + * virDomainEventCallbackListAddID: + * @conn: pointer to the connection + * @cbList: the list + * @eventID: the event ID + * @callback: the callback to add + * @opaque: opaque data tio pass to callback + * + * Internal function to add a callback from a virDomainEventCallbackListPtr + */ +int +virDomainEventCallbackListAddID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + virDomainPtr dom, + int eventID, + virConnectDomainEventGenericCallback callback, + void *opaque, + virFreeCallback freecb) { virDomainEventCallbackPtr event; int i; @@ -259,23 +349,27 @@ virDomainEventCallbackListAdd(virConnectPtr conn, } } /* Allocate new event */ - if (VIR_ALLOC(event) < 0) { - virReportOOMError(); - return -1; - } + if (VIR_ALLOC(event) < 0) + goto no_memory; event->conn = conn; - event->cb = VIR_DOMAIN_EVENT_CALLBACK(callback); - event->eventID = VIR_DOMAIN_EVENT_ID_LIFECYCLE; + event->cb = callback; + event->eventID = eventID; event->opaque = opaque; event->freecb = freecb; - /* Make space on list */ - if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0) { - virReportOOMError(); - VIR_FREE(event); - return -1; + if (dom) { + if (VIR_ALLOC(event->dom) < 0) + goto no_memory; + if (!(event->dom->name = strdup(dom->name))) + goto no_memory; + memcpy(event->dom->uuid, dom->uuid, VIR_UUID_BUFLEN); + event->dom->id = dom->id; } + /* Make space on list */ + if (VIR_REALLOC_N(cbList->callbacks, cbList->count + 1) < 0) + goto no_memory; + event->conn->refs++; cbList->callbacks[cbList->count] = event; @@ -284,6 +378,56 @@ virDomainEventCallbackListAdd(virConnectPtr conn, event->callbackID = cbList->nextID++; return event->callbackID; + +no_memory: + virReportOOMError(); + + if (event) { + if (event->dom) + VIR_FREE(event->dom->name); + VIR_FREE(event->dom); + } + VIR_FREE(event); + return -1; +} + + +int virDomainEventCallbackListCountID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int eventID) +{ + int i; + int count = 0; + + for (i = 0 ; i < cbList->count ; i++) { + if (cbList->callbacks[i]->deleted) + continue; + + if (cbList->callbacks[i]->eventID == eventID && + cbList->callbacks[i]->conn == conn) + count++; + } + + return count; +} + + +int virDomainEventCallbackListEventID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int callbackID) +{ + int i; + + for (i = 0 ; i < cbList->count ; i++) { + if (cbList->callbacks[i]->deleted) + continue; + + if (cbList->callbacks[i]->callbackID == callbackID && + cbList->callbacks[i]->conn == conn) + return cbList->callbacks[i]->eventID; + } + + return -1; } @@ -295,7 +439,8 @@ int virDomainEventCallbackListCount(virDomainEventCallbackListPtr cbList) for (i = 0 ; i < cbList->count ; i++) { if (cbList->callbacks[i]->deleted) continue; - count++; + if (cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE) + count++; } return count; diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h index 8658631d2..db5ad5b94 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -46,24 +46,50 @@ int virDomainEventCallbackListAdd(virConnectPtr conn, void *opaque, virFreeCallback freecb) ATTRIBUTE_NONNULL(1); +int virDomainEventCallbackListAddID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + virDomainPtr dom, + int eventID, + virConnectDomainEventGenericCallback cb, + void *opaque, + virFreeCallback freecb) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(5); + int virDomainEventCallbackListRemove(virConnectPtr conn, virDomainEventCallbackListPtr cbList, virConnectDomainEventCallback callback) ATTRIBUTE_NONNULL(1); - +int virDomainEventCallbackListRemoveID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int callbackID) + ATTRIBUTE_NONNULL(1); int virDomainEventCallbackListRemoveConn(virConnectPtr conn, virDomainEventCallbackListPtr cbList) ATTRIBUTE_NONNULL(1); + int virDomainEventCallbackListMarkDelete(virConnectPtr conn, virDomainEventCallbackListPtr cbList, virConnectDomainEventCallback callback) ATTRIBUTE_NONNULL(1); +int virDomainEventCallbackListMarkDeleteID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int callbackID) + ATTRIBUTE_NONNULL(1); + int virDomainEventCallbackListPurgeMarked(virDomainEventCallbackListPtr cbList); int virDomainEventCallbackListCount(virDomainEventCallbackListPtr cbList); +int virDomainEventCallbackListCountID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int eventID) + ATTRIBUTE_NONNULL(1); +int virDomainEventCallbackListEventID(virConnectPtr conn, + virDomainEventCallbackListPtr cbList, + int callbackID) + ATTRIBUTE_NONNULL(1); /** * Dispatching domain events that come in while diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f1ad6dbf6..19918e5a7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -195,11 +195,17 @@ virDomainClockOffsetTypeFromString; # domain_event.h virDomainEventCallbackListAdd; +virDomainEventCallbackListAddID; virDomainEventCallbackListFree; virDomainEventCallbackListRemove; +virDomainEventCallbackListRemoveID; virDomainEventCallbackListRemoveConn; virDomainEventCallbackListMarkDelete; +virDomainEventCallbackListMarkDeleteID; virDomainEventCallbackListPurgeMarked; +virDomainEventCallbackListCount; +virDomainEventCallbackListCountID; +virDomainEventCallbackListEventID; virDomainEventQueueNew; virDomainEventQueueFree; virDomainEventQueuePop; -- 2.39.5