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@xxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list