1
0
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:
Cole Robinson 2011-01-05 17:51:45 -05:00
parent aaf2b70bae
commit 227d67ca00
3 changed files with 118 additions and 3 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -389,8 +389,12 @@ virDomainEventRTCChangeNewFromObj;
virDomainEventRebootNew;
virDomainEventRebootNewFromDom;
virDomainEventRebootNewFromObj;
virDomainEventStateDeregister;
virDomainEventStateDeregisterAny;
virDomainEventStateFlush;
virDomainEventStateFree;
virDomainEventStateNew;
virDomainEventStateQueue;
virDomainEventWatchdogNewFromDom;
virDomainEventWatchdogNewFromObj;