On Thu, May 12, 2011 at 01:14:25PM -0400, Cole Robinson wrote: > This structure will be used to unify lots of duplicated event handling code > across the state drivers. > > v2: > Check for state == NULL in StateFree > Add NONNULL tagging > Use bool for isDispatching > > Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx> > --- > cfg.mk | 1 + > src/conf/domain_event.c | 94 ++++++++++++++++++++++++++++++++++++---------- > src/conf/domain_event.h | 48 ++++++++++++++++------- > src/libvirt_private.syms | 2 + > 4 files changed, 111 insertions(+), 34 deletions(-) > > diff --git a/cfg.mk b/cfg.mk > index cb059f5..06b638b 100644 > --- a/cfg.mk > +++ b/cfg.mk > @@ -103,6 +103,7 @@ useless_free_options = \ > --name=virDomainEventCallbackListFree \ > --name=virDomainEventFree \ > --name=virDomainEventQueueFree \ > + --name=virDomainEventStateFree \ > --name=virDomainFSDefFree \ > --name=virDomainGraphicsDefFree \ > --name=virDomainHostdevDefFree \ > diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c > index 688bf6c..2771887 100644 > --- a/src/conf/domain_event.c > +++ b/src/conf/domain_event.c > @@ -24,6 +24,7 @@ > #include <config.h> > > #include "domain_event.h" > +#include "event.h" > #include "logging.h" > #include "datatypes.h" > #include "memory.h" > @@ -505,6 +506,25 @@ void virDomainEventFree(virDomainEventPtr event) > VIR_FREE(event); > } > > +/** > + * virDomainEventQueueFree: > + * @queue: pointer to the queue > + * > + * Free the memory in the queue. We process this like a list here > + */ > +void > +virDomainEventQueueFree(virDomainEventQueuePtr queue) > +{ > + int i; > + if (!queue) > + return; > + > + for (i = 0; i < queue->count ; i++) { > + virDomainEventFree(queue->events[i]); > + } > + VIR_FREE(queue->events); > + VIR_FREE(queue); > +} > > virDomainEventQueuePtr virDomainEventQueueNew(void) > { > @@ -518,6 +538,60 @@ virDomainEventQueuePtr virDomainEventQueueNew(void) > return ret; > } > > +/** > + * virDomainEventStateFree: > + * @list: virDomainEventStatePtr to free > + * > + * Free a virDomainEventStatePtr and its members, and unregister the timer. > + */ > +void > +virDomainEventStateFree(virDomainEventStatePtr state) > +{ > + if (!state) > + return; > + > + virDomainEventCallbackListFree(state->callbacks); > + virDomainEventQueueFree(state->queue); > + > + if (state->timer != -1) > + virEventRemoveTimeout(state->timer); > +} > + > +virDomainEventStatePtr > +virDomainEventStateNew(virEventTimeoutCallback timeout_cb, > + void *timeout_opaque, > + virFreeCallback timeout_free) > +{ > + virDomainEventStatePtr state = NULL; > + > + if (VIR_ALLOC(state) < 0) { > + virReportOOMError(); > + goto error; > + } > + > + if (VIR_ALLOC(state->callbacks) < 0) { > + virReportOOMError(); > + goto error; > + } > + > + if (!(state->queue = virDomainEventQueueNew())) { > + goto error; > + } > + > + if ((state->timer = virEventAddTimeout(-1, > + timeout_cb, > + timeout_opaque, > + timeout_free)) < 0) { > + goto error; > + } > + > + return state; > + > +error: > + virDomainEventStateFree(state); > + return NULL; > +} > + > static virDomainEventPtr virDomainEventNewInternal(int eventID, > int id, > const char *name, > @@ -784,26 +858,6 @@ virDomainEventPtr virDomainEventGraphicsNewFromObj(virDomainObjPtr obj, > > > /** > - * virDomainEventQueueFree: > - * @queue: pointer to the queue > - * > - * Free the memory in the queue. We process this like a list here > - */ > -void > -virDomainEventQueueFree(virDomainEventQueuePtr queue) > -{ > - int i; > - if (!queue) > - return; > - > - for (i = 0; i < queue->count ; i++) { > - virDomainEventFree(queue->events[i]); > - } > - VIR_FREE(queue->events); > - VIR_FREE(queue); > -} > - > -/** > * virDomainEventQueuePop: > * @evtQueue: the queue of events > * > diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h > index c03a159..2ac3ecc 100644 > --- a/src/conf/domain_event.h > +++ b/src/conf/domain_event.h > @@ -25,6 +25,7 @@ > #ifndef __DOMAIN_EVENT_H__ > # define __DOMAIN_EVENT_H__ > > +# include "event.h" > # include "domain_conf.h" > > typedef struct _virDomainEventCallback virDomainEventCallback; > @@ -38,6 +39,33 @@ struct _virDomainEventCallbackList { > typedef struct _virDomainEventCallbackList virDomainEventCallbackList; > typedef virDomainEventCallbackList *virDomainEventCallbackListPtr; > > +/** > + * Dispatching domain events that come in while > + * in a call / response rpc > + */ > +typedef struct _virDomainEvent virDomainEvent; > +typedef virDomainEvent *virDomainEventPtr; > + > +struct _virDomainEventQueue { > + unsigned int count; > + virDomainEventPtr *events; > +}; > +typedef struct _virDomainEventQueue virDomainEventQueue; > +typedef virDomainEventQueue *virDomainEventQueuePtr; > + > +struct _virDomainEventState { > + /* The list of domain event callbacks */ > + virDomainEventCallbackListPtr callbacks; > + /* The queue of domain events */ > + virDomainEventQueuePtr queue; > + /* Timer for flushing events queue */ > + int timer; > + /* Flag if we're in process of dispatching */ > + bool isDispatching; > +}; If possible, it would be desirable to make these two struct impls private in domain_event.c > +typedef struct _virDomainEventState virDomainEventState; > +typedef virDomainEventState *virDomainEventStatePtr; > + > void virDomainEventCallbackListFree(virDomainEventCallbackListPtr list); > > int virDomainEventCallbackListAdd(virConnectPtr conn, > @@ -91,20 +119,6 @@ int virDomainEventCallbackListEventID(virConnectPtr conn, > int callbackID) > ATTRIBUTE_NONNULL(1); > > -/** > - * Dispatching domain events that come in while > - * in a call / response rpc > - */ > -typedef struct _virDomainEvent virDomainEvent; > -typedef virDomainEvent *virDomainEventPtr; > - > -struct _virDomainEventQueue { > - unsigned int count; > - virDomainEventPtr *events; > -}; > -typedef struct _virDomainEventQueue virDomainEventQueue; > -typedef virDomainEventQueue *virDomainEventQueuePtr; > - > virDomainEventQueuePtr virDomainEventQueueNew(void); > > virDomainEventPtr virDomainEventNew(int id, const char *name, const unsigned char *uuid, int type, int detail); > @@ -164,6 +178,12 @@ virDomainEventQueuePop(virDomainEventQueuePtr evtQueue); > > void virDomainEventFree(virDomainEventPtr event); > void virDomainEventQueueFree(virDomainEventQueuePtr queue); > +void virDomainEventStateFree(virDomainEventStatePtr state); > +virDomainEventStatePtr > +virDomainEventStateNew(virEventTimeoutCallback timeout_cb, > + void *timeout_opaque, > + virFreeCallback timeout_free) > + ATTRIBUTE_NONNULL(1); > > typedef void (*virDomainEventDispatchFunc)(virConnectPtr conn, > virDomainEventPtr event, > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 7e5b1d7..d4ad0c8 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -389,6 +389,8 @@ virDomainEventRTCChangeNewFromObj; > virDomainEventRebootNew; > virDomainEventRebootNewFromDom; > virDomainEventRebootNewFromObj; > +virDomainEventStateFree; > +virDomainEventStateNew; > 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