[libvirt] [PATCH 2/7] domain_event: Add common domain event queue/flush helpers
Daniel P. Berrange
berrange at redhat.com
Fri May 13 09:23:51 UTC 2011
On Thu, May 12, 2011 at 01:14:26PM -0400, Cole Robinson wrote:
> 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
>
> Signed-off-by: Cole Robinson <crobinso at redhat.com>
> ---
> src/conf/domain_event.c | 93 +++++++++++++++++++++++++++++++++++++++++++++-
> src/conf/domain_event.h | 24 +++++++++++-
> src/libvirt_private.syms | 4 ++
> 3 files changed, 118 insertions(+), 3 deletions(-)
>
> diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
> index 2771887..b85765e 100644
> --- a/src/conf/domain_event.c
> +++ b/src/conf/domain_event.c
> @@ -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);
> +}
> diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
> index 2ac3ecc..efc05f9 100644
> --- a/src/conf/domain_event.h
> +++ b/src/conf/domain_event.h
> @@ -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
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index d4ad0c8..c98efdc 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -389,8 +389,12 @@ virDomainEventRTCChangeNewFromObj;
> virDomainEventRebootNew;
> virDomainEventRebootNewFromDom;
> virDomainEventRebootNewFromObj;
> +virDomainEventStateDeregister;
> +virDomainEventStateDeregisterAny;
> +virDomainEventStateFlush;
> virDomainEventStateFree;
> virDomainEventStateNew;
> +virDomainEventStateQueue;
> virDomainEventWatchdogNewFromDom;
> virDomainEventWatchdogNewFromObj;
ACK
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list