mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
domain_event: Add common domain event queue/flush helpers
The same code for queueing, flushing, and deregistering events exists in multiple drivers, which will soon use these common functions. v2: Adjust libvirt_private.syms isDispatching bool fixes NONNULL tagging v3: Add requireTimer parameter to virDomainEventStateNew
This commit is contained in:
parent
aaf2b70bae
commit
227d67ca00
@ -557,10 +557,21 @@ virDomainEventStateFree(virDomainEventStatePtr state)
|
||||
virEventRemoveTimeout(state->timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
virFreeCallback timeout_free,
|
||||
bool requireTimer)
|
||||
{
|
||||
virDomainEventStatePtr state = NULL;
|
||||
|
||||
@ -582,7 +593,14 @@ virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
||||
timeout_cb,
|
||||
timeout_opaque,
|
||||
timeout_free)) < 0) {
|
||||
goto error;
|
||||
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;
|
||||
@ -1059,3 +1077,74 @@ void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
|
||||
VIR_FREE(queue->events);
|
||||
queue->count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
virDomainEventStateQueue(virDomainEventStatePtr state,
|
||||
virDomainEventPtr event)
|
||||
{
|
||||
if (state->timer < 0) {
|
||||
virDomainEventFree(event);
|
||||
return;
|
||||
}
|
||||
|
||||
if (virDomainEventQueuePush(state->queue, event) < 0) {
|
||||
VIR_DEBUG("Error adding event to queue");
|
||||
virDomainEventFree(event);
|
||||
}
|
||||
|
||||
if (state->queue->count == 1)
|
||||
virEventUpdateTimeout(state->timer, 0);
|
||||
}
|
||||
|
||||
void
|
||||
virDomainEventStateFlush(virDomainEventStatePtr state,
|
||||
virDomainEventDispatchFunc dispatchFunc,
|
||||
void *opaque)
|
||||
{
|
||||
virDomainEventQueue tempQueue;
|
||||
|
||||
state->isDispatching = true;
|
||||
|
||||
/* Copy the queue, so we're reentrant safe when dispatchFunc drops the
|
||||
* driver lock */
|
||||
tempQueue.count = state->queue->count;
|
||||
tempQueue.events = state->queue->events;
|
||||
state->queue->count = 0;
|
||||
state->queue->events = NULL;
|
||||
|
||||
virEventUpdateTimeout(state->timer, -1);
|
||||
virDomainEventQueueDispatch(&tempQueue,
|
||||
state->callbacks,
|
||||
dispatchFunc,
|
||||
opaque);
|
||||
|
||||
/* Purge any deleted callbacks */
|
||||
virDomainEventCallbackListPurgeMarked(state->callbacks);
|
||||
|
||||
state->isDispatching = false;
|
||||
}
|
||||
|
||||
int
|
||||
virDomainEventStateDeregister(virConnectPtr conn,
|
||||
virDomainEventStatePtr state,
|
||||
virConnectDomainEventCallback callback)
|
||||
{
|
||||
if (state->isDispatching)
|
||||
return virDomainEventCallbackListMarkDelete(conn,
|
||||
state->callbacks, callback);
|
||||
else
|
||||
return virDomainEventCallbackListRemove(conn, state->callbacks, callback);
|
||||
}
|
||||
|
||||
int
|
||||
virDomainEventStateDeregisterAny(virConnectPtr conn,
|
||||
virDomainEventStatePtr state,
|
||||
int callbackID)
|
||||
{
|
||||
if (state->isDispatching)
|
||||
return virDomainEventCallbackListMarkDeleteID(conn,
|
||||
state->callbacks, callbackID);
|
||||
else
|
||||
return virDomainEventCallbackListRemoveID(conn,
|
||||
state->callbacks, callbackID);
|
||||
}
|
||||
|
@ -182,7 +182,8 @@ void virDomainEventStateFree(virDomainEventStatePtr state);
|
||||
virDomainEventStatePtr
|
||||
virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
||||
void *timeout_opaque,
|
||||
virFreeCallback timeout_free)
|
||||
virFreeCallback timeout_free,
|
||||
bool requireTimer)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
|
||||
@ -205,4 +206,25 @@ void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
|
||||
virDomainEventDispatchFunc dispatch,
|
||||
void *opaque);
|
||||
|
||||
|
||||
void
|
||||
virDomainEventStateQueue(virDomainEventStatePtr state,
|
||||
virDomainEventPtr event)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
void
|
||||
virDomainEventStateFlush(virDomainEventStatePtr state,
|
||||
virDomainEventDispatchFunc dispatchFunc,
|
||||
void *opaque)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
int
|
||||
virDomainEventStateDeregister(virConnectPtr conn,
|
||||
virDomainEventStatePtr state,
|
||||
virConnectDomainEventCallback callback)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||
int
|
||||
virDomainEventStateDeregisterAny(virConnectPtr conn,
|
||||
virDomainEventStatePtr state,
|
||||
int callbackID)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
#endif
|
||||
|
@ -389,8 +389,12 @@ virDomainEventRTCChangeNewFromObj;
|
||||
virDomainEventRebootNew;
|
||||
virDomainEventRebootNewFromDom;
|
||||
virDomainEventRebootNewFromObj;
|
||||
virDomainEventStateDeregister;
|
||||
virDomainEventStateDeregisterAny;
|
||||
virDomainEventStateFlush;
|
||||
virDomainEventStateFree;
|
||||
virDomainEventStateNew;
|
||||
virDomainEventStateQueue;
|
||||
virDomainEventWatchdogNewFromDom;
|
||||
virDomainEventWatchdogNewFromObj;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user