[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