mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 09:53:10 +00: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);
|
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
|
virDomainEventStatePtr
|
||||||
virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
||||||
void *timeout_opaque,
|
void *timeout_opaque,
|
||||||
virFreeCallback timeout_free)
|
virFreeCallback timeout_free,
|
||||||
|
bool requireTimer)
|
||||||
{
|
{
|
||||||
virDomainEventStatePtr state = NULL;
|
virDomainEventStatePtr state = NULL;
|
||||||
|
|
||||||
@ -582,8 +593,15 @@ virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
|||||||
timeout_cb,
|
timeout_cb,
|
||||||
timeout_opaque,
|
timeout_opaque,
|
||||||
timeout_free)) < 0) {
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
||||||
@ -1059,3 +1077,74 @@ void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
|
|||||||
VIR_FREE(queue->events);
|
VIR_FREE(queue->events);
|
||||||
queue->count = 0;
|
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
|
virDomainEventStatePtr
|
||||||
virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
|
||||||
void *timeout_opaque,
|
void *timeout_opaque,
|
||||||
virFreeCallback timeout_free)
|
virFreeCallback timeout_free,
|
||||||
|
bool requireTimer)
|
||||||
ATTRIBUTE_NONNULL(1);
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
|
typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn,
|
||||||
@ -205,4 +206,25 @@ void virDomainEventQueueDispatch(virDomainEventQueuePtr queue,
|
|||||||
virDomainEventDispatchFunc dispatch,
|
virDomainEventDispatchFunc dispatch,
|
||||||
void *opaque);
|
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
|
#endif
|
||||||
|
@ -389,8 +389,12 @@ virDomainEventRTCChangeNewFromObj;
|
|||||||
virDomainEventRebootNew;
|
virDomainEventRebootNew;
|
||||||
virDomainEventRebootNewFromDom;
|
virDomainEventRebootNewFromDom;
|
||||||
virDomainEventRebootNewFromObj;
|
virDomainEventRebootNewFromObj;
|
||||||
|
virDomainEventStateDeregister;
|
||||||
|
virDomainEventStateDeregisterAny;
|
||||||
|
virDomainEventStateFlush;
|
||||||
virDomainEventStateFree;
|
virDomainEventStateFree;
|
||||||
virDomainEventStateNew;
|
virDomainEventStateNew;
|
||||||
|
virDomainEventStateQueue;
|
||||||
virDomainEventWatchdogNewFromDom;
|
virDomainEventWatchdogNewFromDom;
|
||||||
virDomainEventWatchdogNewFromObj;
|
virDomainEventWatchdogNewFromObj;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user