/** * 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(VIR_ERR_INTERNAL_ERROR, "%s", _("could not find event callback for removal")); return -1; }
/** * virDomainEventQueuePop: * @evtQueue: the queue of events * * Internal function to pop off, and return the front of the queue * NOTE: The caller is responsible for freeing the returned object * * Returns: virDomainEventPtr on success NULL on failure. */ virDomainEventPtr virDomainEventQueuePop(virDomainEventQueuePtr evtQueue) { virDomainEventPtr ret; if (!evtQueue || evtQueue->count == 0 ) { eventReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("event queue is empty, nothing to pop")); return NULL; } ret = evtQueue->events[0]; memmove(evtQueue->events, evtQueue->events + 1, sizeof(*(evtQueue->events)) * (evtQueue->count - 1)); if (VIR_REALLOC_N(evtQueue->events, evtQueue->count - 1) < 0) { ; /* Failure to reduce memory allocation isn't fatal */ } evtQueue->count--; return ret; }
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(VIR_ERR_INTERNAL_ERROR, "%s", _("could not find event callback for deletion")); return -1; }
int virDomainEventCallbackListMarkDelete(virConnectPtr conn, virDomainEventCallbackListPtr cbList, virConnectDomainEventCallback callback) { int i; for (i = 0 ; i < cbList->count ; i++) { if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) && cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE && cbList->callbacks[i]->conn == conn) { cbList->callbacks[i]->deleted = 1; return 0; } } eventReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("could not find event callback for deletion")); return -1; }
/** * virDomainEventStateNew: * @timeout_cb: virEventTimeoutCallback to call when timer expires * @timeout_opaque: Data for timeout_cb * @timeout_free: Optional virFreeCallback for freeing timeout_opaque * @requireTimer: If true, return an error if registering the timer fails. * This is fatal for drivers that sit behind the daemon * (qemu, lxc), since there should always be a event impl * registered. */ virDomainEventStatePtr virDomainEventStateNew(virEventTimeoutCallback timeout_cb, void *timeout_opaque, virFreeCallback timeout_free, bool requireTimer) { virDomainEventStatePtr state = NULL; if (VIR_ALLOC(state) < 0) { virReportOOMError(); goto error; } if (VIR_ALLOC(state->callbacks) < 0) { virReportOOMError(); goto error; } if (!(state->queue = virDomainEventQueueNew())) { goto error; } if ((state->timer = virEventAddTimeout(-1, timeout_cb, timeout_opaque, timeout_free)) < 0) { if (requireTimer == false) { VIR_DEBUG("virEventAddTimeout failed: No addTimeoutImpl defined. " "continuing without events."); } else { eventReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("could not initialize domain event timer")); goto error; } } return state; error: virDomainEventStateFree(state); return NULL; }
/** * virDomainEventCallbackListRemove: * @conn: pointer to the connection * @cbList: the list * @callback: the callback to remove * * Internal function to remove a callback from a virDomainEventCallbackListPtr */ static int virDomainEventCallbackListRemove(virConnectPtr conn, virDomainEventCallbackListPtr cbList, virConnectDomainEventCallback callback) { int ret = 0; int i; for (i = 0 ; i < cbList->count ; i++) { if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) && cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE && 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--; for (i = 0 ; i < cbList->count ; i++) { if (!cbList->callbacks[i]->deleted) ret++; } return ret; } } eventReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("could not find event callback for removal")); return -1; }
/** * 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; /* Check incoming */ if ( !cbList ) { return -1; } /* check if we already have this callback on our list */ for (i = 0 ; i < cbList->count ; i++) { if (cbList->callbacks[i]->cb == VIR_DOMAIN_EVENT_CALLBACK(callback) && cbList->callbacks[i]->eventID == VIR_DOMAIN_EVENT_ID_LIFECYCLE && cbList->callbacks[i]->conn == conn) { eventReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("event callback already tracked")); return -1; } } /* Allocate new event */ if (VIR_ALLOC(event) < 0) goto no_memory; event->conn = conn; event->cb = callback; event->eventID = eventID; event->opaque = opaque; event->freecb = freecb; 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; cbList->count++; 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; }