diff --git a/cfg.mk b/cfg.mk index cb059f5396adbcc8eda8f7f093fff0e3c41e77f2..06b638b43f6fff7694afaa8621856b831fa29af9 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 688bf6c517bb073fd42372bee96f97c515a34825..27718876933b66fe83a4baf8ee60ef473058ed73 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -24,6 +24,7 @@ #include #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, @@ -783,26 +857,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 c03a159c0b757b96ffed0f27096de441ec7c07c0..2ac3ecc98c0e9164db41107ac5547dd13e72dd3e 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; +}; +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 7e5b1d7e9262910e55fde5ced269523e01409ec7..d4ad0c80db7404858256e846c2fd3bfc7a35d1b6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -389,6 +389,8 @@ virDomainEventRTCChangeNewFromObj; virDomainEventRebootNew; virDomainEventRebootNewFromDom; virDomainEventRebootNewFromObj; +virDomainEventStateFree; +virDomainEventStateNew; virDomainEventWatchdogNewFromDom; virDomainEventWatchdogNewFromObj;